xref: /aosp_15_r20/external/googleapis/google/firestore/v1/query.proto (revision d5c09012810ac0c9f33fe448fb6da8260d444cc9)
1// Copyright 2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15syntax = "proto3";
16
17package google.firestore.v1;
18
19import "google/api/field_behavior.proto";
20import "google/firestore/v1/document.proto";
21import "google/protobuf/wrappers.proto";
22
23option csharp_namespace = "Google.Cloud.Firestore.V1";
24option go_package = "cloud.google.com/go/firestore/apiv1/firestorepb;firestorepb";
25option java_multiple_files = true;
26option java_outer_classname = "QueryProto";
27option java_package = "com.google.firestore.v1";
28option objc_class_prefix = "GCFS";
29option php_namespace = "Google\\Cloud\\Firestore\\V1";
30option ruby_package = "Google::Cloud::Firestore::V1";
31
32// A Firestore query.
33//
34// The query stages are executed in the following order:
35// 1. from
36// 2. where
37// 3. select
38// 4. order_by + start_at + end_at
39// 5. offset
40// 6. limit
41message StructuredQuery {
42  // A selection of a collection, such as `messages as m1`.
43  message CollectionSelector {
44    // The collection ID.
45    // When set, selects only collections with this ID.
46    string collection_id = 2;
47
48    // When false, selects only collections that are immediate children of
49    // the `parent` specified in the containing `RunQueryRequest`.
50    // When true, selects all descendant collections.
51    bool all_descendants = 3;
52  }
53
54  // A filter.
55  message Filter {
56    // The type of filter.
57    oneof filter_type {
58      // A composite filter.
59      CompositeFilter composite_filter = 1;
60
61      // A filter on a document field.
62      FieldFilter field_filter = 2;
63
64      // A filter that takes exactly one argument.
65      UnaryFilter unary_filter = 3;
66    }
67  }
68
69  // A filter that merges multiple other filters using the given operator.
70  message CompositeFilter {
71    // A composite filter operator.
72    enum Operator {
73      // Unspecified. This value must not be used.
74      OPERATOR_UNSPECIFIED = 0;
75
76      // Documents are required to satisfy all of the combined filters.
77      AND = 1;
78
79      // Documents are required to satisfy at least one of the combined filters.
80      OR = 2;
81    }
82
83    // The operator for combining multiple filters.
84    Operator op = 1;
85
86    // The list of filters to combine.
87    //
88    // Requires:
89    //
90    // * At least one filter is present.
91    repeated Filter filters = 2;
92  }
93
94  // A filter on a specific field.
95  message FieldFilter {
96    // A field filter operator.
97    enum Operator {
98      // Unspecified. This value must not be used.
99      OPERATOR_UNSPECIFIED = 0;
100
101      // The given `field` is less than the given `value`.
102      //
103      // Requires:
104      //
105      // * That `field` come first in `order_by`.
106      LESS_THAN = 1;
107
108      // The given `field` is less than or equal to the given `value`.
109      //
110      // Requires:
111      //
112      // * That `field` come first in `order_by`.
113      LESS_THAN_OR_EQUAL = 2;
114
115      // The given `field` is greater than the given `value`.
116      //
117      // Requires:
118      //
119      // * That `field` come first in `order_by`.
120      GREATER_THAN = 3;
121
122      // The given `field` is greater than or equal to the given `value`.
123      //
124      // Requires:
125      //
126      // * That `field` come first in `order_by`.
127      GREATER_THAN_OR_EQUAL = 4;
128
129      // The given `field` is equal to the given `value`.
130      EQUAL = 5;
131
132      // The given `field` is not equal to the given `value`.
133      //
134      // Requires:
135      //
136      // * No other `NOT_EQUAL`, `NOT_IN`, `IS_NOT_NULL`, or `IS_NOT_NAN`.
137      // * That `field` comes first in the `order_by`.
138      NOT_EQUAL = 6;
139
140      // The given `field` is an array that contains the given `value`.
141      ARRAY_CONTAINS = 7;
142
143      // The given `field` is equal to at least one value in the given array.
144      //
145      // Requires:
146      //
147      // * That `value` is a non-empty `ArrayValue`, subject to disjunction
148      //   limits.
149      // * No `NOT_IN` filters in the same query.
150      IN = 8;
151
152      // The given `field` is an array that contains any of the values in the
153      // given array.
154      //
155      // Requires:
156      //
157      // * That `value` is a non-empty `ArrayValue`, subject to disjunction
158      //   limits.
159      // * No other `ARRAY_CONTAINS_ANY` filters within the same disjunction.
160      // * No `NOT_IN` filters in the same query.
161      ARRAY_CONTAINS_ANY = 9;
162
163      // The value of the `field` is not in the given array.
164      //
165      // Requires:
166      //
167      // * That `value` is a non-empty `ArrayValue` with at most 10 values.
168      // * No other `OR`, `IN`, `ARRAY_CONTAINS_ANY`, `NOT_IN`, `NOT_EQUAL`,
169      //   `IS_NOT_NULL`, or `IS_NOT_NAN`.
170      // * That `field` comes first in the `order_by`.
171      NOT_IN = 10;
172    }
173
174    // The field to filter by.
175    FieldReference field = 1;
176
177    // The operator to filter by.
178    Operator op = 2;
179
180    // The value to compare to.
181    Value value = 3;
182  }
183
184  // A filter with a single operand.
185  message UnaryFilter {
186    // A unary operator.
187    enum Operator {
188      // Unspecified. This value must not be used.
189      OPERATOR_UNSPECIFIED = 0;
190
191      // The given `field` is equal to `NaN`.
192      IS_NAN = 2;
193
194      // The given `field` is equal to `NULL`.
195      IS_NULL = 3;
196
197      // The given `field` is not equal to `NaN`.
198      //
199      // Requires:
200      //
201      // * No other `NOT_EQUAL`, `NOT_IN`, `IS_NOT_NULL`, or `IS_NOT_NAN`.
202      // * That `field` comes first in the `order_by`.
203      IS_NOT_NAN = 4;
204
205      // The given `field` is not equal to `NULL`.
206      //
207      // Requires:
208      //
209      // * A single `NOT_EQUAL`, `NOT_IN`, `IS_NOT_NULL`, or `IS_NOT_NAN`.
210      // * That `field` comes first in the `order_by`.
211      IS_NOT_NULL = 5;
212    }
213
214    // The unary operator to apply.
215    Operator op = 1;
216
217    // The argument to the filter.
218    oneof operand_type {
219      // The field to which to apply the operator.
220      FieldReference field = 2;
221    }
222  }
223
224  // An order on a field.
225  message Order {
226    // The field to order by.
227    FieldReference field = 1;
228
229    // The direction to order by. Defaults to `ASCENDING`.
230    Direction direction = 2;
231  }
232
233  // A sort direction.
234  enum Direction {
235    // Unspecified.
236    DIRECTION_UNSPECIFIED = 0;
237
238    // Ascending.
239    ASCENDING = 1;
240
241    // Descending.
242    DESCENDING = 2;
243  }
244
245  // A reference to a field in a document, ex: `stats.operations`.
246  message FieldReference {
247    // A reference to a field in a document.
248    //
249    // Requires:
250    //
251    // * MUST be a dot-delimited (`.`) string of segments, where each segment
252    // conforms to [document field name][google.firestore.v1.Document.fields]
253    // limitations.
254    string field_path = 2;
255  }
256
257  // The projection of document's fields to return.
258  message Projection {
259    // The fields to return.
260    //
261    // If empty, all fields are returned. To only return the name
262    // of the document, use `['__name__']`.
263    repeated FieldReference fields = 2;
264  }
265
266  // Nearest Neighbors search config.
267  message FindNearest {
268    // The distance measure to use when comparing vectors.
269    enum DistanceMeasure {
270      // Should not be set.
271      DISTANCE_MEASURE_UNSPECIFIED = 0;
272
273      // Measures the EUCLIDEAN distance between the vectors. See
274      // [Euclidean](https://en.wikipedia.org/wiki/Euclidean_distance) to learn
275      // more
276      EUCLIDEAN = 1;
277
278      // Compares vectors based on the angle between them, which allows you to
279      // measure similarity that isn't based on the vectors magnitude.
280      // We recommend using DOT_PRODUCT with unit normalized vectors instead of
281      // COSINE distance, which is mathematically equivalent with better
282      // performance. See [Cosine
283      // Similarity](https://en.wikipedia.org/wiki/Cosine_similarity) to learn
284      // more.
285      COSINE = 2;
286
287      // Similar to cosine but is affected by the magnitude of the vectors. See
288      // [Dot Product](https://en.wikipedia.org/wiki/Dot_product) to learn more.
289      DOT_PRODUCT = 3;
290    }
291
292    // Required. An indexed vector field to search upon. Only documents which
293    // contain vectors whose dimensionality match the query_vector can be
294    // returned.
295    FieldReference vector_field = 1 [(google.api.field_behavior) = REQUIRED];
296
297    // Required. The query vector that we are searching on. Must be a vector of
298    // no more than 2048 dimensions.
299    Value query_vector = 2 [(google.api.field_behavior) = REQUIRED];
300
301    // Required. The Distance Measure to use, required.
302    DistanceMeasure distance_measure = 3
303        [(google.api.field_behavior) = REQUIRED];
304
305    // Required. The number of nearest neighbors to return. Must be a positive
306    // integer of no more than 1000.
307    google.protobuf.Int32Value limit = 4
308        [(google.api.field_behavior) = REQUIRED];
309  }
310
311  // Optional sub-set of the fields to return.
312  //
313  // This acts as a [DocumentMask][google.firestore.v1.DocumentMask] over the
314  // documents returned from a query. When not set, assumes that the caller
315  // wants all fields returned.
316  Projection select = 1;
317
318  // The collections to query.
319  repeated CollectionSelector from = 2;
320
321  // The filter to apply.
322  Filter where = 3;
323
324  // The order to apply to the query results.
325  //
326  // Firestore allows callers to provide a full ordering, a partial ordering, or
327  // no ordering at all. In all cases, Firestore guarantees a stable ordering
328  // through the following rules:
329  //
330  //  * The `order_by` is required to reference all fields used with an
331  //    inequality filter.
332  //  * All fields that are required to be in the `order_by` but are not already
333  //    present are appended in lexicographical ordering of the field name.
334  //  * If an order on `__name__` is not specified, it is appended by default.
335  //
336  // Fields are appended with the same sort direction as the last order
337  // specified, or 'ASCENDING' if no order was specified. For example:
338  //
339  //  * `ORDER BY a` becomes `ORDER BY a ASC, __name__ ASC`
340  //  * `ORDER BY a DESC` becomes `ORDER BY a DESC, __name__ DESC`
341  //  * `WHERE a > 1` becomes `WHERE a > 1 ORDER BY a ASC, __name__ ASC`
342  //  * `WHERE __name__ > ... AND a > 1` becomes
343  //     `WHERE __name__ > ... AND a > 1 ORDER BY a ASC, __name__ ASC`
344  repeated Order order_by = 4;
345
346  // A potential prefix of a position in the result set to start the query at.
347  //
348  // The ordering of the result set is based on the `ORDER BY` clause of the
349  // original query.
350  //
351  // ```
352  // SELECT * FROM k WHERE a = 1 AND b > 2 ORDER BY b ASC, __name__ ASC;
353  // ```
354  //
355  // This query's results are ordered by `(b ASC, __name__ ASC)`.
356  //
357  // Cursors can reference either the full ordering or a prefix of the location,
358  // though it cannot reference more fields than what are in the provided
359  // `ORDER BY`.
360  //
361  // Continuing off the example above, attaching the following start cursors
362  // will have varying impact:
363  //
364  // - `START BEFORE (2, /k/123)`: start the query right before `a = 1 AND
365  //    b > 2 AND __name__ > /k/123`.
366  // - `START AFTER (10)`: start the query right after `a = 1 AND b > 10`.
367  //
368  // Unlike `OFFSET` which requires scanning over the first N results to skip,
369  // a start cursor allows the query to begin at a logical position. This
370  // position is not required to match an actual result, it will scan forward
371  // from this position to find the next document.
372  //
373  // Requires:
374  //
375  // * The number of values cannot be greater than the number of fields
376  //   specified in the `ORDER BY` clause.
377  Cursor start_at = 7;
378
379  // A potential prefix of a position in the result set to end the query at.
380  //
381  // This is similar to `START_AT` but with it controlling the end position
382  // rather than the start position.
383  //
384  // Requires:
385  //
386  // * The number of values cannot be greater than the number of fields
387  //   specified in the `ORDER BY` clause.
388  Cursor end_at = 8;
389
390  // The number of documents to skip before returning the first result.
391  //
392  // This applies after the constraints specified by the `WHERE`, `START AT`, &
393  // `END AT` but before the `LIMIT` clause.
394  //
395  // Requires:
396  //
397  // * The value must be greater than or equal to zero if specified.
398  int32 offset = 6;
399
400  // The maximum number of results to return.
401  //
402  // Applies after all other constraints.
403  //
404  // Requires:
405  //
406  // * The value must be greater than or equal to zero if specified.
407  google.protobuf.Int32Value limit = 5;
408
409  // Optional. A potential Nearest Neighbors Search.
410  //
411  // Applies after all other filters and ordering.
412  //
413  // Finds the closest vector embeddings to the given query vector.
414  FindNearest find_nearest = 9 [(google.api.field_behavior) = OPTIONAL];
415}
416
417// Firestore query for running an aggregation over a
418// [StructuredQuery][google.firestore.v1.StructuredQuery].
419message StructuredAggregationQuery {
420  // Defines an aggregation that produces a single result.
421  message Aggregation {
422    // Count of documents that match the query.
423    //
424    // The `COUNT(*)` aggregation function operates on the entire document
425    // so it does not require a field reference.
426    message Count {
427      // Optional. Optional constraint on the maximum number of documents to
428      // count.
429      //
430      // This provides a way to set an upper bound on the number of documents
431      // to scan, limiting latency, and cost.
432      //
433      // Unspecified is interpreted as no bound.
434      //
435      // High-Level Example:
436      //
437      // ```
438      // AGGREGATE COUNT_UP_TO(1000) OVER ( SELECT * FROM k );
439      // ```
440      //
441      // Requires:
442      //
443      // * Must be greater than zero when present.
444      google.protobuf.Int64Value up_to = 1
445          [(google.api.field_behavior) = OPTIONAL];
446    }
447
448    // Sum of the values of the requested field.
449    //
450    // * Only numeric values will be aggregated. All non-numeric values
451    // including `NULL` are skipped.
452    //
453    // * If the aggregated values contain `NaN`, returns `NaN`. Infinity math
454    // follows IEEE-754 standards.
455    //
456    // * If the aggregated value set is empty, returns 0.
457    //
458    // * Returns a 64-bit integer if all aggregated numbers are integers and the
459    // sum result does not overflow. Otherwise, the result is returned as a
460    // double. Note that even if all the aggregated values are integers, the
461    // result is returned as a double if it cannot fit within a 64-bit signed
462    // integer. When this occurs, the returned value will lose precision.
463    //
464    // * When underflow occurs, floating-point aggregation is non-deterministic.
465    // This means that running the same query repeatedly without any changes to
466    // the underlying values could produce slightly different results each
467    // time. In those cases, values should be stored as integers over
468    // floating-point numbers.
469    message Sum {
470      // The field to aggregate on.
471      StructuredQuery.FieldReference field = 1;
472    }
473
474    // Average of the values of the requested field.
475    //
476    // * Only numeric values will be aggregated. All non-numeric values
477    // including `NULL` are skipped.
478    //
479    // * If the aggregated values contain `NaN`, returns `NaN`. Infinity math
480    // follows IEEE-754 standards.
481    //
482    // * If the aggregated value set is empty, returns `NULL`.
483    //
484    // * Always returns the result as a double.
485    message Avg {
486      // The field to aggregate on.
487      StructuredQuery.FieldReference field = 1;
488    }
489
490    // The type of aggregation to perform, required.
491    oneof operator {
492      // Count aggregator.
493      Count count = 1;
494
495      // Sum aggregator.
496      Sum sum = 2;
497
498      // Average aggregator.
499      Avg avg = 3;
500    }
501
502    // Optional. Optional name of the field to store the result of the
503    // aggregation into.
504    //
505    // If not provided, Firestore will pick a default name following the format
506    // `field_<incremental_id++>`. For example:
507    //
508    // ```
509    // AGGREGATE
510    //   COUNT_UP_TO(1) AS count_up_to_1,
511    //   COUNT_UP_TO(2),
512    //   COUNT_UP_TO(3) AS count_up_to_3,
513    //   COUNT(*)
514    // OVER (
515    //   ...
516    // );
517    // ```
518    //
519    // becomes:
520    //
521    // ```
522    // AGGREGATE
523    //   COUNT_UP_TO(1) AS count_up_to_1,
524    //   COUNT_UP_TO(2) AS field_1,
525    //   COUNT_UP_TO(3) AS count_up_to_3,
526    //   COUNT(*) AS field_2
527    // OVER (
528    //   ...
529    // );
530    // ```
531    //
532    // Requires:
533    //
534    // * Must be unique across all aggregation aliases.
535    // * Conform to [document field name][google.firestore.v1.Document.fields]
536    // limitations.
537    string alias = 7 [(google.api.field_behavior) = OPTIONAL];
538  }
539
540  // The base query to aggregate over.
541  oneof query_type {
542    // Nested structured query.
543    StructuredQuery structured_query = 1;
544  }
545
546  // Optional. Series of aggregations to apply over the results of the
547  // `structured_query`.
548  //
549  // Requires:
550  //
551  // * A minimum of one and maximum of five aggregations per query.
552  repeated Aggregation aggregations = 3
553      [(google.api.field_behavior) = OPTIONAL];
554}
555
556// A position in a query result set.
557message Cursor {
558  // The values that represent a position, in the order they appear in
559  // the order by clause of a query.
560  //
561  // Can contain fewer values than specified in the order by clause.
562  repeated Value values = 1;
563
564  // If the position is just before or just after the given values, relative
565  // to the sort order defined by the query.
566  bool before = 2;
567}
568