• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 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 = "proto2";
16
17package icing.lib;
18
19import "icing/proto/document.proto";
20import "icing/proto/logging.proto";
21import "icing/proto/scoring.proto";
22import "icing/proto/status.proto";
23import "icing/proto/term.proto";
24
25option java_package = "com.google.android.icing.proto";
26option java_multiple_files = true;
27option objc_class_prefix = "ICNG";
28
29// Client-supplied specifications on what documents to retrieve.
30// Next tag: 15
31message SearchSpecProto {
32  // REQUIRED: The "raw" query string that users may type. For example, "cat"
33  // will search for documents with the term cat in it.
34  optional string query = 1;
35
36  // Indicates how the query terms should match terms in the index.
37  //
38  // TermMatchType.Code=UNKNOWN
39  // Should never purposely be set and may lead to undefined behavior. This is
40  // used for backwards compatibility reasons.
41  //
42  // TermMatchType.Code=EXACT_ONLY
43  // Query terms will only match exact tokens in the index.
44  // Ex. A query term "foo" will only match indexed token "foo", and not "foot"
45  // or "football"
46  //
47  // TermMatchType.Code=PREFIX
48  // Query terms will match indexed tokens when the query term is a prefix of
49  // the token.
50  // Ex. A query term "foo" will match indexed tokens like "foo", "foot", and
51  // "football".
52  //
53  // TermMatchType.Code=STEMMING
54  // Query terms will match indexed tokens when the query term is a stem of
55  // the token, or relates to the token via the same stem.
56  // Ex. A query term "dance" will match indexed tokens like "dance", "dances",
57  // and "dancing".
58  //
59  // TODO: b/344915547 - Refactor this to be a repeated field so that clients
60  // can choose multiple fuzzy match types.
61  optional TermMatchType.Code term_match_type = 2;
62
63  // OPTIONAL: Only search for documents that have the specified namespaces. If
64  // unset, the query will search over all namespaces. Note that this applies to
65  // the entire 'query'. To issue different queries for different namespaces,
66  // separate Search()'s will need to be made.
67  repeated string namespace_filters = 3;
68
69  // OPTIONAL: Only search for documents that have the specified schema types.
70  // If unset, the query will search over all schema types. Note that this
71  // applies to the entire 'query'. To issue different queries for different
72  // schema types, separate Search()'s will need to be made. Also note that
73  // schema filters will not be expanded for polymorphism.
74  repeated string schema_type_filters = 4;
75
76  // OPTIONAL: Only search for documents under the specified namespaces and
77  // uris. If unset, all documents will be searched.
78  //
79  // All given NamespaceDocumentUriGroup must specify at least one
80  // document_uri. To exclude a namespace, use namespace_filters instead.
81  repeated NamespaceDocumentUriGroup document_uri_filters = 14;
82
83  // Timestamp taken just before sending proto across the JNI boundary from java
84  // to native side.
85  optional int64 java_to_native_start_timestamp_ms = 5;
86
87  // OPTIONAL: If this field is present, join documents based on a nested
88  // SearchSpec.
89  optional JoinSpecProto join_spec = 7;
90
91  // Features enabled in this search spec.
92  repeated string enabled_features = 8;
93
94  // OPTIONAL: Whether to use the read-only implementation of
95  // IcingSearchEngine::Search.
96  // The read-only version enables multiple queries to be performed concurrently
97  // as it only acquires the read lock at IcingSearchEngine's level.
98  // Finer-grained locks are implemented around code paths that write changes to
99  // Icing during Search.
100  optional bool use_read_only_search = 9 [default = true];
101
102  // TODO(b/294266822): Handle multiple property filter lists for same schema
103  // type.
104  // How to specify a subset of properties to be searched. If no type property
105  // filter has been specified for a schema type (no TypePropertyMask for the
106  // given schema type), then *all* properties of that schema type will be
107  // searched. If an empty property filter is specified for a given schema type
108  // (TypePropertyMask for the given schema type has empty paths field), no
109  // properties of that schema type will be searched.
110  repeated TypePropertyMask type_property_filters = 10;
111
112  // The vectors to be used in embedding queries.
113  repeated PropertyProto.VectorProto embedding_query_vectors = 11;
114
115  message EmbeddingQueryMetricType {
116    enum Code {
117      UNKNOWN = 0;
118      COSINE = 1;
119      DOT_PRODUCT = 2;
120      EUCLIDEAN = 3;
121    }
122  }
123
124  // The default metric type used to calculate the scores for embedding
125  // queries.
126  optional EmbeddingQueryMetricType.Code embedding_query_metric_type = 12;
127
128  // Strings to be used as parameters in the query. The strings will be treated
129  // as pure TEXT and will be normalized and tokenized.
130  repeated string query_parameter_strings = 13;
131
132  reserved 6;
133}
134
135// Client-supplied specifications on what to include/how to format the search
136// results.
137// Next tag: 10
138message ResultSpecProto {
139  // The results will be returned in pages, and num_per_page specifies the
140  // number of documents in one page.
141  optional int32 num_per_page = 1 [default = 10];
142
143  // Whether to collect and return debug_info in the SearchResultProto.
144  optional bool debug_info = 2;
145
146  // How to provide snippeting information in the SearchResultProto.
147  // Next tag: 5
148  message SnippetSpecProto {
149    // Only the first num_to_snippet documents will have snippet information
150    // provided. If set to 0, snippeting is disabled.
151    optional int32 num_to_snippet = 1;
152
153    // Only the first num_matches_per_property matches for a single section will
154    // have snippet information provided. If set to 0, snippeting is disabled.
155    optional int32 num_matches_per_property = 2;
156
157    // How large of a window to provide. Windows start at
158    // max_window_utf32_length / 2 bytes before the middle of the matching token
159    // and end at max_window_utf32_length / 2 bytes after the middle of the
160    // matching token. Windowing respects token boundaries. Therefore, the
161    // returned window may be smaller than requested. Setting
162    // max_window_utf32_length to 0 will disable windowing information. If
163    // matches enabled is also set to false, then snippeting is disabled. Ex.
164    // max_window_utf32_length = 16. "foo bar baz bat rat" with a query of "baz"
165    // will return a window of "bar baz bat" which is only 11 bytes long.
166    optional int32 max_window_utf32_length = 3;
167
168    // Whether to get match info for embedding semantic search. Embedding match
169    // info is returned in
170    // ResultProto.SnippetProto.EntryProto.EmbeddingMatchSnippetProto and
171    // contains the following information:
172    // - The score of the matched embedding vector.
173    // - The index of the embedding query for this vector match.
174    // - The metric type of the embedding query for this vector match.
175    optional bool get_embedding_match_info = 4;
176  }
177  optional SnippetSpecProto snippet_spec = 3;
178
179  // How to specify a subset of properties to retrieve. If no type property mask
180  // has been specified for a schema type, then *all* properties of that schema
181  // type will be retrieved.
182  repeated TypePropertyMask type_property_masks = 4;
183
184  // Groupings of namespaces and schema types whose total returned results
185  // should be limited together.
186  // Next tag: 3
187  message ResultGrouping {
188    // Grouping of namespace and schema type.
189    // Next tag: 3
190    message Entry {
191      // The namespace in this grouping that should be returned.
192      // This field should be empty if ResultGroupingType is SCHEMA_TYPE
193      optional string namespace = 1;
194
195      // The schema in this grouping that should be returned.
196      // This field should be empty if ResultGroupingType is NAMESPACE
197      optional string schema = 2;
198    }
199
200    // Identifier for namespace and schema type pairs.
201    repeated Entry entry_groupings = 1;
202
203    // The maximum number of results in this grouping that should be returned.
204    optional int32 max_results = 2;
205  }
206
207  // How to limit the number of results returned per set of namespaces or schema
208  // type. If results match for a namespace or schema type that is not present
209  // in any result groupings, then those results will be returned without limit.
210  //
211  // Non-existent namespaces and/or schema type will be ignored.
212  //
213  // Example : Suppose that there are four namespaces each with three results
214  // matching the query for "foo". Without any result groupings, Icing would
215  // return the following results:
216  // ["ns0doc0", "ns0doc1", "ns1doc0", "ns3doc0", "ns0doc2", "ns3doc1",
217  //  "ns2doc1", "ns3doc2", "ns2doc0", "ns1doc1", "ns2doc2", "ns1doc1"].
218  //
219  // The following result groupings will be returned if that the
220  // ResultGroupingType is set to NAMESPACE:
221  // [ { [ {"namespace0"} ], 2 }, { [ {"namespace1"}, {"namespace2"} ], 2} ]
222  //
223  // The following results will be returned:
224  // ["ns0doc0", "ns0doc1", "ns1doc0", "ns3doc0", "ns3doc1", "ns2doc1",
225  //  "ns3doc2"].
226  repeated ResultGrouping result_groupings = 5;
227
228  // The threshold of total bytes of all documents to cutoff, in order to limit
229  // # of bytes in a single page.
230  // Note that it doesn't guarantee the result # of bytes will be smaller, equal
231  // to, or larger than the threshold. Instead, it is just a threshold to
232  // cutoff, and only guarantees total bytes of search results will exceed the
233  // threshold by less than the size of the final search result.
234  optional int32 num_total_bytes_per_page_threshold = 6
235      [default = 2147483647];  // INT_MAX
236
237  // The value by which the search results will get grouped by.
238  // Can get grouped by schema type, namespace (default), or by namespace and
239  // schema type.
240  enum ResultGroupingType {
241    NONE = 0;
242    SCHEMA_TYPE = 1;
243    NAMESPACE = 2;
244    NAMESPACE_AND_SCHEMA_TYPE = 3;
245  }
246  optional ResultGroupingType result_group_type = 7;
247
248  // The max # of child documents will be attached and returned in the result
249  // for each parent. It is only used for join API.
250  optional int32 max_joined_children_per_parent_to_return = 8;
251
252  // The max # of results being scored and ranked.
253  // Running time of ScoringProcessor and Ranker is O(num_to_score) according to
254  // results of //icing/scoring:score-and-rank_benchmark. Note that
255  // the process includes scoring, building a heap, and popping results from the
256  // heap.
257  //
258  // 30000 results can be scored and ranked within 3 ms on a Pixel 3 XL
259  // according to results of
260  // //icing/scoring:score-and-rank_benchmark, so set it as the
261  // default value.
262  optional int32 num_to_score = 9 [default = 30000];
263}
264
265// The representation of a single match within a DocumentProto property.
266//
267// Example : A document whose content is "Necesito comprar comida mañana." and a
268// query for "mana" with window=15
269// Next tag: 12
270message SnippetMatchProto {
271  // The index of the byte in the string at which the match begins and the
272  // length in bytes of the match.
273  //
274  // For the example above, the values of these fields would be
275  // exact_match_byte_position=24, exact_match_byte_length=7 "mañana"
276  optional int32 exact_match_byte_position = 2;
277  optional int32 exact_match_byte_length = 3;
278
279  // The length in bytes of the subterm that matches the query. The beginning of
280  // the submatch is the same as exact_match_byte_position.
281  //
282  // For the example above, the value of this field would be 5. With
283  // exact_match_byte_position=24 above, it would produce the substring "maña"
284  optional int32 submatch_byte_length = 10;
285
286  // The index of the UTF-16 code unit in the string at which the match begins
287  // and the length in UTF-16 code units of the match. This is for use with
288  // UTF-16 encoded strings like Java.lang.String.
289  //
290  // For the example above, the values of these fields would be
291  // exact_match_utf16_position=24, exact_match_utf16_length=6 "mañana"
292  optional int32 exact_match_utf16_position = 6;
293  optional int32 exact_match_utf16_length = 7;
294
295  // The length in UTF-16 code units of the subterm that matches the query. The
296  // beginning of the submatch is the same as exact_match_utf16_position. This
297  // is for use with UTF-16 encoded strings like Java.lang.String.
298  //
299  // For the example above, the value of this field would be 4. With
300  // exact_match_utf16_position=24 above, it would produce the substring "maña"
301  optional int32 submatch_utf16_length = 11;
302
303  // The index of the byte in the string at which the suggested snippet window
304  // begins and the length in bytes of the window.
305  //
306  // For the example above, the values of these fields would be
307  // window_byte_position=17, window_byte_length=15 "comida mañana."
308  optional int32 window_byte_position = 4;
309  optional int32 window_byte_length = 5;
310
311  // The index of the UTF-16 code unit in the string at which the suggested
312  // snippet window begins and the length in UTF-16 code units of the window.
313  // This is for use with UTF-16 encoded strings like Java.lang.String.
314  //
315  // For the example above, the values of these fields would be
316  // window_utf16_position=17, window_utf16_length=14 "comida mañana."
317  optional int32 window_utf16_position = 8;
318  optional int32 window_utf16_length = 9;
319
320  reserved 1;
321}
322
323// The representation of a single embedding vector match within a DocumentProto
324// property.
325//
326// Next tag: 4
327message EmbeddingMatchSnippetProto {
328  // Semantic score of the matched embedding vector.
329  optional double semantic_score = 1;
330
331  // Index of the embedding query for this vector match.
332  optional int32 embedding_query_vector_index = 2;
333
334  // The metric type of the embedding query for this vector match.
335  optional SearchSpecProto.EmbeddingQueryMetricType.Code
336      embedding_query_metric_type = 3;
337}
338
339// A Proto representing all snippets for a single DocumentProto.
340// Next tag: 2
341message SnippetProto {
342  // A pair of property name and all snippet matches that correspond to the
343  // property values in the corresponding DocumentProto.
344  // Next tag: 4
345  message EntryProto {
346    // A property path indicating which property in the DocumentProto these
347    // snippets correspond to. Property paths will contain 1) property names,
348    // 2) the property separator character '.' used to represent nested property
349    // and 3) indices surrounded by brackets to represent a specific value in
350    // that property.
351    //
352    // Example properties:
353    // - 'body'               : the first and only string value of a top-level
354    //                          property called 'body'.
355    // - 'sender.name'        : the first and only string value of a property
356    //                          called 'name' that is a subproperty of a
357    //                          property called 'sender'.
358    // - 'bcc[1].emailaddress': the first and only string value of a property
359    //                          called 'emailaddress' that is a subproperty of
360    //                          the second document value of a property called
361    //                          'bcc'.
362    // - 'attachments[0]'     : the first (of more than one) string value of a
363    //                          property called 'attachments'.
364    // NOTE: If there is only a single value for a property (like
365    // 'sender.name'), then no value index will be added to the property path.
366    // An index of [0] is implied. If there is more than one value for a
367    // property, then the value index will be added to the property path (like
368    // 'attachements[0]').
369    optional string property_name = 1;
370
371    // The term-match info for this property. Only populated if the property is
372    // a string.
373    repeated SnippetMatchProto snippet_matches = 2;
374
375    // The embedding-match info for this property. Only populated if the
376    // property is an embedding vector and get_embedding_match_info is set to
377    // true in the ResultSpecProto.
378    repeated EmbeddingMatchSnippetProto embedding_matches = 3;
379  }
380  // Properties that do not appear in entries do not contain any matches.
381  repeated EntryProto entries = 1;
382}
383
384// Icing lib-supplied results from a search results.
385// Next tag: 6
386message SearchResultProto {
387  // Status code can be one of:
388  //   OK
389  //   FAILED_PRECONDITION
390  //   INVALID_ARGUMENT
391  //   ABORTED
392  //   INTERNAL
393  //
394  // See status.proto for more details.
395  //
396  // TODO(b/147699081): Fix error codes: +ABORTED.
397  // go/icing-library-apis.
398  optional StatusProto status = 1;
399
400  // The Results that matched the query. Empty if there was an error.
401  // Next tag: 6
402  message ResultProto {
403    // Document that matches the SearchSpecProto.
404    optional DocumentProto document = 1;
405
406    // Snippeting information for the document if requested in the
407    // ResultSpecProto. A default instance, if not requested.
408    optional SnippetProto snippet = 2;
409
410    // The score that the document was ranked by. The meaning of this score is
411    // determined by ScoringSpecProto.rank_by.
412    optional double score = 3;
413
414    // The child documents that were joined to a parent document.
415    repeated ResultProto joined_results = 4;
416
417    // Extra helpful scores as specified by
418    // ScoringSpecProto.additional_advanced_scoring_expressions. The scores will
419    // not be used for ranking.
420    repeated double additional_scores = 5 [packed = true];
421  }
422  repeated ResultProto results = 2;
423
424  // Various debug fields. Not populated if ResultSpecProto.debug_info = false.
425  // Next tag: 4
426  message DebugInfoProto {
427    // The internal representation of the actual query string that was executed.
428    // This may be different from the SearchSpecProto.query if the original
429    // query was malformed.
430    optional string executed_query = 3;
431
432    reserved 1, 2;
433  }
434  optional DebugInfoProto debug_info = 3;
435
436  // An opaque token used internally to keep track of information needed for
437  // pagination. A valid pagination token is required to fetch other pages of
438  // results. A value 0 means that there're no more pages.
439  // LINT.IfChange(next_page_token)
440  optional uint64 next_page_token = 4;
441  // LINT.ThenChange(//depot/google3/icing/result/result-state-manager.h:kInvalidNextPageToken)
442
443  // Stats for query execution performance.
444  optional QueryStatsProto query_stats = 5;
445}
446
447// Next tag: 3
448message TypePropertyMask {
449  // The schema type to which these property masks should apply.
450  // If the schema type is the wildcard ("*"), then the type property masks
451  // will apply to all results of types that don't have their own, specific
452  // type property mask entry.
453  optional string schema_type = 1;
454
455  // The property masks specifying the property to be retrieved. Property
456  // masks must be composed only of property names, property separators (the
457  // '.' character). For example, "subject", "recipients.name". Specifying no
458  // property masks will result in *no* properties being retrieved.
459  repeated string paths = 2;
460}
461
462// Next tag: 5
463// TODO(b/394875109): Rename it to GetRequestProto to be consistent with the
464// name in AppSearch.
465message GetResultSpecProto {
466  optional string namespace_requested = 2;
467  repeated string ids = 3;
468
469  // How to specify a subset of properties to retrieve. If no type property mask
470  // has been specified for a schema type, then *all* properties of that schema
471  // type will be retrieved.
472  repeated TypePropertyMask type_property_masks = 1;
473
474  // The maximum number of accumulated bytes for the documents to return in the
475  // result. This limit is to prevent the result from being too large, and we
476  // can't send it over VM boundary, which has transaction limit 600KB.
477  optional int32 num_total_document_bytes_to_return = 4
478      [default = 2147483647];  // INT_MAX
479}
480
481// Next tag: 12
482message SuggestionSpecProto {
483  // REQUIRED: The "raw" prefix string that users may type. For example, "f"
484  // will search for suggested query that start with "f" like "foo", "fool".
485  optional string prefix = 1;
486
487  // OPTIONAL: Only search for suggestions that under the specified namespaces.
488  // If unset, the suggestion will search over all namespaces. Note that this
489  // applies to the entire 'prefix'. To issue different suggestions for
490  // different namespaces, separate RunSuggestion()'s will need to be made.
491  repeated string namespace_filters = 2;
492
493  // REQUIRED: The number of suggestions to be returned.
494  optional int32 num_to_return = 3;
495
496  // Indicates how the suggestion terms should be scored and ranked.
497  optional SuggestionScoringSpecProto scoring_spec = 4;
498
499  // OPTIONAL: Only search for suggestions that under the specified
500  // DocumentUris. If unset, the suggestion will search over all Documents.
501  //
502  // All namespace in the given NamespaceDocumentUriGroup should match the
503  // namespace_filters. i.e. appears in the namespace_filter or namespace_filter
504  // is empty.
505  //
506  // All given NamespaceDocumentUriGroup cannot have empty. Please use the
507  // namespace_filter to exclude a namespace.
508  //
509  // Note that this applies to the entire 'prefix'. To issue different
510  // suggestions for different DocumentIds, separate RunSuggestion()'s will need
511  // to be made.
512  repeated NamespaceDocumentUriGroup document_uri_filters = 5;
513
514  // OPTIONAL: Only search for suggestions that under the specified schemas.
515  // If unset, the suggestion will search over all schema types. Note that this
516  // applies to the entire 'prefix'. To issue different suggestions for
517  // different schema typs, separate RunSuggestion()'s will need to be made.
518  // Also note that schema filters will not be expanded for polymorphism.
519  repeated string schema_type_filters = 6;
520
521  // OPTIONAL: Only search for suggestions that under the specified types and
522  // properties.
523  //
524  // If unset, the suggestion will search over all types.
525  // If the TypePropertyMask.paths is unset, the suggestion will search over all
526  // properties under the TypePropertyMask.schema_type.
527  //
528  // Note that this applies to the entire 'prefix'. To issue different
529  // suggestions for different types, separate RunSuggestion()'s will need to be
530  // made.
531  repeated TypePropertyMask type_property_filters = 7;
532
533  // The vectors to be used in embedding queries.
534  repeated PropertyProto.VectorProto embedding_query_vectors = 8;
535
536  // The default metric type used to calculate the scores for embedding
537  // queries.
538  optional SearchSpecProto.EmbeddingQueryMetricType.Code
539      embedding_query_metric_type = 9;
540
541  // Strings to be used as parameters in the query. The strings will be treated
542  // as pure TEXT and will be normalized and tokenized.
543  repeated string query_parameter_strings = 10;
544
545  // Features enabled in this suggestion spec.
546  repeated string enabled_features = 11;
547}
548
549// A group that holds namespace and document_uris under it.
550message NamespaceDocumentUriGroup {
551  optional string namespace_ = 1;
552  repeated string document_uris = 2;
553}
554
555// Next tag: 3
556message SuggestionResponse {
557  message Suggestion {
558    // The suggested query string for client to search for.
559    optional string query = 1;
560  }
561
562  // Status code can be one of:
563  //   OK
564  //   FAILED_PRECONDITION
565  //   INTERNAL
566  //
567  // See status.proto for more details.
568  optional StatusProto status = 1;
569
570  repeated Suggestion suggestions = 2;
571}
572
573// Specification for a left outer join.
574//
575// Next tag: 7
576message JoinSpecProto {
577  // Collection of several specs that will be used for searching and joining
578  // child documents.
579  //
580  // Next tag: 4
581  message NestedSpecProto {
582    // A nested SearchSpec that will be used to retrieve child documents. If you
583    // are only looking to join on a specific type documents, you could set a
584    // schema filter in this SearchSpec. This includes the nested search query.
585    // See SearchSpecProto.
586    optional SearchSpecProto search_spec = 1;
587
588    // A nested ScoringSpec that will be used to score child documents.
589    // See ScoringSpecProto.
590    optional ScoringSpecProto scoring_spec = 2;
591
592    // A nested ResultSpec that will be used to format child documents in the
593    // result joined documents, e.g. snippeting, projection.
594    // See ResultSpecProto.
595    optional ResultSpecProto result_spec = 3;
596  }
597  optional NestedSpecProto nested_spec = 1;
598
599  // The equivalent of a primary key in SQL. This is an expression that will be
600  // used to match child documents from the nested search to this document. One
601  // such expression is qualifiedId(). When used, it means the contents of
602  // child_property_expression property in the child documents must be equal to
603  // the qualified id.
604  // TODO(b/256022027) allow for parent_property_expression to be any property
605  // of the parent document.
606  optional string parent_property_expression = 2;
607
608  // The equivalent of a foreign key in SQL. This defines an equality constraint
609  // between a property in a child document and a property in the parent
610  // document. For example, if you want to join child documents which an
611  // entityId property containing a fully qualified document id,
612  // child_property_expression can be set to "entityId".
613  // TODO(b/256022027) figure out how to allow this to refer to documents
614  // outside of same pkg+db+ns.
615  optional string child_property_expression = 3;
616
617  // The max number of child documents to join to a parent document.
618  // DEPRECATED: use ResultSpecProto.max_joined_children_per_parent_to_return to
619  // control the number of children that are returned. There is no supported
620  // control for the number of children being scored at this time.
621  optional int32 max_joined_child_count = 4 [deprecated = true];
622
623  // The strategy by which to score the aggregation of child documents. For
624  // example, you might want to know which entity document has the most actions
625  // taken on it. If JOIN_AGGREGATE_SCORE is used in the base SearchSpecProto,
626  // the COUNT value will rank entity documents based on the number of child
627  // documents.
628  message AggregationScoringStrategy {
629    enum Code {
630      NONE = 0;  // No aggregation strategy for child documents and use parent
631                 // document score.
632      COUNT = 1;
633      MIN = 2;
634      AVG = 3;
635      MAX = 4;
636      SUM = 5;
637    }
638  }
639  optional AggregationScoringStrategy.Code aggregation_scoring_strategy = 5;
640}
641