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