1// Copyright 2021 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.cloud.retail.v2;
18
19import "google/api/annotations.proto";
20import "google/api/client.proto";
21import "google/api/field_behavior.proto";
22import "google/api/resource.proto";
23import "google/cloud/retail/v2/common.proto";
24import "google/cloud/retail/v2/product.proto";
25import "google/protobuf/field_mask.proto";
26import "google/protobuf/struct.proto";
27
28option csharp_namespace = "Google.Cloud.Retail.V2";
29option go_package = "cloud.google.com/go/retail/apiv2/retailpb;retailpb";
30option java_multiple_files = true;
31option java_outer_classname = "SearchServiceProto";
32option java_package = "com.google.cloud.retail.v2";
33option objc_class_prefix = "RETAIL";
34option php_namespace = "Google\\Cloud\\Retail\\V2";
35option ruby_package = "Google::Cloud::Retail::V2";
36option (google.api.resource_definition) = {
37  type: "retail.googleapis.com/Experiment"
38  pattern: "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}"
39};
40
41// Service for search.
42//
43// This feature is only available for users who have Retail Search enabled.
44// Enable Retail Search on Cloud Console before using this feature.
45service SearchService {
46  option (google.api.default_host) = "retail.googleapis.com";
47  option (google.api.oauth_scopes) =
48      "https://www.googleapis.com/auth/cloud-platform";
49
50  // Performs a search.
51  //
52  // This feature is only available for users who have Retail Search enabled.
53  // Enable Retail Search on Cloud Console before using this feature.
54  rpc Search(SearchRequest) returns (SearchResponse) {
55    option (google.api.http) = {
56      post: "/v2/{placement=projects/*/locations/*/catalogs/*/placements/*}:search"
57      body: "*"
58      additional_bindings {
59        post: "/v2/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:search"
60        body: "*"
61      }
62    };
63  }
64}
65
66// Request message for
67// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] method.
68message SearchRequest {
69  // A facet specification to perform faceted search.
70  message FacetSpec {
71    // Specifies how a facet is computed.
72    message FacetKey {
73      // Required. Supported textual and numerical facet keys in
74      // [Product][google.cloud.retail.v2.Product] object, over which the facet
75      // values are computed. Facet key is case-sensitive.
76      //
77      // Allowed facet keys when
78      // [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query]
79      // is not specified:
80      //
81      // * textual_field =
82      //     * "brands"
83      //     * "categories"
84      //     * "genders"
85      //     * "ageGroups"
86      //     * "availability"
87      //     * "colorFamilies"
88      //     * "colors"
89      //     * "sizes"
90      //     * "materials"
91      //     * "patterns"
92      //     * "conditions"
93      //     * "attributes.key"
94      //     * "pickupInStore"
95      //     * "shipToStore"
96      //     * "sameDayDelivery"
97      //     * "nextDayDelivery"
98      //     * "customFulfillment1"
99      //     * "customFulfillment2"
100      //     * "customFulfillment3"
101      //     * "customFulfillment4"
102      //     * "customFulfillment5"
103      //     * "inventory(place_id,attributes.key)"
104      //
105      // * numerical_field =
106      //     * "price"
107      //     * "discount"
108      //     * "rating"
109      //     * "ratingCount"
110      //     * "attributes.key"
111      //     * "inventory(place_id,price)"
112      //     * "inventory(place_id,original_price)"
113      //     * "inventory(place_id,attributes.key)"
114      string key = 1 [(google.api.field_behavior) = REQUIRED];
115
116      // Set only if values should be bucketized into intervals. Must be set
117      // for facets with numerical values. Must not be set for facet with text
118      // values. Maximum number of intervals is 40.
119      //
120      // For all numerical facet keys that appear in the list of products from
121      // the catalog, the percentiles 0, 10, 30, 50, 70, 90 and 100 are
122      // computed from their distribution weekly. If the model assigns a high
123      // score to a numerical facet key and its intervals are not specified in
124      // the search request, these percentiles will become the bounds
125      // for its intervals and will be returned in the response. If the
126      // facet key intervals are specified in the request, then the specified
127      // intervals will be returned instead.
128      repeated Interval intervals = 2;
129
130      // Only get facet for the given restricted values. For example, when using
131      // "pickupInStore" as key and set restricted values to
132      // ["store123", "store456"], only facets for "store123" and "store456" are
133      // returned. Only supported on predefined textual fields, custom textual
134      // attributes and fulfillments. Maximum is 20.
135      //
136      // Must be set for the fulfillment facet keys:
137      //
138      // * pickupInStore
139      //
140      // * shipToStore
141      //
142      // * sameDayDelivery
143      //
144      // * nextDayDelivery
145      //
146      // * customFulfillment1
147      //
148      // * customFulfillment2
149      //
150      // * customFulfillment3
151      //
152      // * customFulfillment4
153      //
154      // * customFulfillment5
155      repeated string restricted_values = 3;
156
157      // Only get facet values that start with the given string prefix. For
158      // example, suppose "categories" has three values "Women > Shoe",
159      // "Women > Dress" and "Men > Shoe". If set "prefixes" to "Women", the
160      // "categories" facet will give only "Women > Shoe" and "Women > Dress".
161      // Only supported on textual fields. Maximum is 10.
162      repeated string prefixes = 8;
163
164      // Only get facet values that contains the given strings. For example,
165      // suppose "categories" has three values "Women > Shoe",
166      // "Women > Dress" and "Men > Shoe". If set "contains" to "Shoe", the
167      // "categories" facet will give only "Women > Shoe" and "Men > Shoe".
168      // Only supported on textual fields. Maximum is 10.
169      repeated string contains = 9;
170
171      // True to make facet keys case insensitive when getting faceting
172      // values with prefixes or contains; false otherwise.
173      bool case_insensitive = 10;
174
175      // The order in which
176      // [SearchResponse.Facet.values][google.cloud.retail.v2.SearchResponse.Facet.values]
177      // are returned.
178      //
179      // Allowed values are:
180      //
181      // * "count desc", which means order by
182      // [SearchResponse.Facet.values.count][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count]
183      // descending.
184      //
185      // * "value desc", which means order by
186      // [SearchResponse.Facet.values.value][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value]
187      // descending.
188      //   Only applies to textual facets.
189      //
190      // If not set, textual values are sorted in [natural
191      // order](https://en.wikipedia.org/wiki/Natural_sort_order); numerical
192      // intervals are sorted in the order given by
193      // [FacetSpec.FacetKey.intervals][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals];
194      // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
195      // are sorted in the order given by
196      // [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.restricted_values].
197      string order_by = 4;
198
199      // The query that is used to compute facet for the given facet key.
200      // When provided, it will override the default behavior of facet
201      // computation. The query syntax is the same as a filter expression. See
202      // [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
203      // detail syntax and limitations. Notice that there is no limitation on
204      // [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
205      // when query is specified.
206      //
207      // In the response,
208      // [SearchResponse.Facet.values.value][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value]
209      // will be always "1" and
210      // [SearchResponse.Facet.values.count][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count]
211      // will be the number of results that match the query.
212      //
213      // For example, you can set a customized facet for "shipToStore",
214      // where
215      // [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
216      // is "customizedShipToStore", and
217      // [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query]
218      // is "availability: ANY(\"IN_STOCK\") AND shipToStore: ANY(\"123\")".
219      // Then the facet will count the products that are both in stock and ship
220      // to store "123".
221      string query = 5;
222
223      // Returns the min and max value for each numerical facet intervals.
224      // Ignored for textual facets.
225      bool return_min_max = 11;
226    }
227
228    // Required. The facet key specification.
229    FacetKey facet_key = 1 [(google.api.field_behavior) = REQUIRED];
230
231    // Maximum of facet values that should be returned for this facet. If
232    // unspecified, defaults to 50. The maximum allowed value is 300. Values
233    // above 300 will be coerced to 300.
234    //
235    // If this field is negative, an INVALID_ARGUMENT is returned.
236    int32 limit = 2;
237
238    // List of keys to exclude when faceting.
239    //
240    //
241    // By default,
242    // [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
243    // is not excluded from the filter unless it is listed in this field.
244    //
245    // Listing a facet key in this field allows its values to appear as facet
246    // results, even when they are filtered out of search results. Using this
247    // field does not affect what search results are returned.
248    //
249    // For example, suppose there are 100 products with the color facet "Red"
250    // and 200 products with the color facet "Blue". A query containing the
251    // filter "colorFamilies:ANY("Red")" and having "colorFamilies" as
252    // [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key]
253    // would by default return only "Red" products in the search results, and
254    // also return "Red" with count 100 as the only color facet. Although there
255    // are also blue products available, "Blue" would not be shown as an
256    // available facet value.
257    //
258    // If "colorFamilies" is listed in "excludedFilterKeys", then the query
259    // returns the facet values "Red" with count 100 and "Blue" with count
260    // 200, because the "colorFamilies" key is now excluded from the filter.
261    // Because this field doesn't affect search results, the search results
262    // are still correctly filtered to return only "Red" products.
263    //
264    // A maximum of 100 values are allowed. Otherwise, an INVALID_ARGUMENT error
265    // is returned.
266    repeated string excluded_filter_keys = 3;
267
268    // Enables dynamic position for this facet. If set to true, the position of
269    // this facet among all facets in the response is determined by Google
270    // Retail Search. It will be ordered together with dynamic facets if dynamic
271    // facets is enabled. If set to false, the position of this facet in the
272    // response will be the same as in the request, and it will be ranked before
273    // the facets with dynamic position enable and all dynamic facets.
274    //
275    // For example, you may always want to have rating facet returned in
276    // the response, but it's not necessarily to always display the rating facet
277    // at the top. In that case, you can set enable_dynamic_position to true so
278    // that the position of rating facet in response will be determined by
279    // Google Retail Search.
280    //
281    // Another example, assuming you have the following facets in the request:
282    //
283    // * "rating", enable_dynamic_position = true
284    //
285    // * "price", enable_dynamic_position = false
286    //
287    // * "brands", enable_dynamic_position = false
288    //
289    // And also you have a dynamic facets enable, which will generate a facet
290    // 'gender'. Then the final order of the facets in the response can be
291    // ("price", "brands", "rating", "gender") or ("price", "brands", "gender",
292    // "rating") depends on how Google Retail Search orders "gender" and
293    // "rating" facets. However, notice that "price" and "brands" will always be
294    // ranked at 1st and 2nd position since their enable_dynamic_position are
295    // false.
296    bool enable_dynamic_position = 4;
297  }
298
299  // The specifications of dynamically generated facets.
300  message DynamicFacetSpec {
301    // Enum to control DynamicFacet mode
302    enum Mode {
303      // Default value.
304      MODE_UNSPECIFIED = 0;
305
306      // Disable Dynamic Facet.
307      DISABLED = 1;
308
309      // Automatic mode built by Google Retail Search.
310      ENABLED = 2;
311    }
312
313    // Mode of the DynamicFacet feature.
314    // Defaults to
315    // [Mode.DISABLED][google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode.DISABLED]
316    // if it's unset.
317    Mode mode = 1;
318  }
319
320  // Boost specification to boost certain items.
321  message BoostSpec {
322    // Boost applies to products which match a condition.
323    message ConditionBoostSpec {
324      // An expression which specifies a boost condition. The syntax and
325      // supported fields are the same as a filter expression. See
326      // [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
327      // detail syntax and limitations.
328      //
329      // Examples:
330      //
331      // * To boost products with product ID "product_1" or "product_2", and
332      // color
333      //   "Red" or "Blue":
334      //     * (id: ANY("product_1", "product_2")) AND (colorFamilies:
335      //     ANY("Red","Blue"))
336      string condition = 1;
337
338      // Strength of the condition boost, which should be in [-1, 1]. Negative
339      // boost means demotion. Default is 0.0.
340      //
341      // Setting to 1.0 gives the item a big promotion. However, it does not
342      // necessarily mean that the boosted item will be the top result at all
343      // times, nor that other items will be excluded. Results could still be
344      // shown even when none of them matches the condition. And results that
345      // are significantly more relevant to the search query can still trump
346      // your heavily favored but irrelevant items.
347      //
348      // Setting to -1.0 gives the item a big demotion. However, results that
349      // are deeply relevant might still be shown. The item will have an
350      // upstream battle to get a fairly high ranking, but it is not blocked out
351      // completely.
352      //
353      // Setting to 0.0 means no boost applied. The boosting condition is
354      // ignored.
355      float boost = 2;
356    }
357
358    // Condition boost specifications. If a product matches multiple conditions
359    // in the specifictions, boost scores from these specifications are all
360    // applied and combined in a non-linear way. Maximum number of
361    // specifications is 20.
362    repeated ConditionBoostSpec condition_boost_specs = 1;
363
364    // Whether to skip boostspec validation. If this field is set to true,
365    // invalid
366    // [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]
367    // will be ignored and valid
368    // [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]
369    // will still be applied.
370    optional bool skip_boost_spec_validation = 2;
371  }
372
373  // Specification to determine under which conditions query expansion should
374  // occur.
375  message QueryExpansionSpec {
376    // Enum describing under which condition query expansion should occur.
377    enum Condition {
378      // Unspecified query expansion condition. In this case, server behavior
379      // defaults to
380      // [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED].
381      CONDITION_UNSPECIFIED = 0;
382
383      // Disabled query expansion. Only the exact search query is used, even if
384      // [SearchResponse.total_size][google.cloud.retail.v2.SearchResponse.total_size]
385      // is zero.
386      DISABLED = 1;
387
388      // Automatic query expansion built by Google Retail Search.
389      AUTO = 3;
390    }
391
392    // The condition under which query expansion should occur. Default to
393    // [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED].
394    Condition condition = 1;
395
396    // Whether to pin unexpanded results. If this field is set to true,
397    // unexpanded products are always at the top of the search results, followed
398    // by the expanded results.
399    bool pin_unexpanded_results = 2;
400  }
401
402  // The specification for personalization.
403  message PersonalizationSpec {
404    // The personalization mode of each search request.
405    enum Mode {
406      // Default value. In this case, server behavior defaults to
407      // [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO].
408      MODE_UNSPECIFIED = 0;
409
410      // Let CRS decide whether to use personalization based on quality of user
411      // event data.
412      AUTO = 1;
413
414      // Disable personalization.
415      DISABLED = 2;
416    }
417
418    // Defaults to
419    // [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO].
420    Mode mode = 1;
421  }
422
423  // The specification for query spell correction.
424  message SpellCorrectionSpec {
425    // Enum describing under which mode spell correction should occur.
426    enum Mode {
427      // Unspecified spell correction mode. In this case, server behavior
428      // defaults to
429      // [Mode.AUTO][google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO].
430      MODE_UNSPECIFIED = 0;
431
432      // Google Retail Search will try to find a spell suggestion if there
433      // is any and put in the
434      // [SearchResponse.corrected_query][google.cloud.retail.v2.SearchResponse.corrected_query].
435      // The spell suggestion will not be used as the search query.
436      SUGGESTION_ONLY = 1;
437
438      // Automatic spell correction built by Google Retail Search. Search will
439      // be based on the corrected query if found.
440      AUTO = 2;
441    }
442
443    // The mode under which spell correction should take effect to
444    // replace the original search query. Default to
445    // [Mode.AUTO][google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO].
446    Mode mode = 1;
447  }
448
449  // The search mode of each search request.
450  enum SearchMode {
451    // Default value. In this case both product search and faceted search will
452    // be performed. Both
453    // [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult]
454    // and [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet]
455    // will be returned.
456    SEARCH_MODE_UNSPECIFIED = 0;
457
458    // Only product search will be performed. The faceted search will be
459    // disabled.
460    //
461    // Only
462    // [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult]
463    // will be returned.
464    // [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] will
465    // not be returned, even if
466    // [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs]
467    // or
468    // [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2.SearchRequest.dynamic_facet_spec]
469    // is set.
470    PRODUCT_SEARCH_ONLY = 1;
471
472    // Only faceted search will be performed. The product search will be
473    // disabled.
474    //
475    // When in this mode, one or both of
476    // [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs]
477    // and
478    // [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2.SearchRequest.dynamic_facet_spec]
479    // should be set. Otherwise, an INVALID_ARGUMENT error is returned. Only
480    // [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] will
481    // be returned.
482    // [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult]
483    // will not be returned.
484    FACETED_SEARCH_ONLY = 2;
485  }
486
487  // Required. The resource name of the Retail Search serving config, such as
488  // `projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`
489  // or the name of the legacy placement resource, such as
490  // `projects/*/locations/global/catalogs/default_catalog/placements/default_search`.
491  // This field is used to identify the serving config name and the set
492  // of models that will be used to make the search.
493  string placement = 1 [(google.api.field_behavior) = REQUIRED];
494
495  // The branch resource name, such as
496  // `projects/*/locations/global/catalogs/default_catalog/branches/0`.
497  //
498  // Use "default_branch" as the branch ID or leave this field empty, to search
499  // products under the default branch.
500  string branch = 2 [
501    (google.api.resource_reference) = { type: "retail.googleapis.com/Branch" }
502  ];
503
504  // Raw search query.
505  //
506  // If this field is empty, the request is considered a category browsing
507  // request and returned results are based on
508  // [filter][google.cloud.retail.v2.SearchRequest.filter] and
509  // [page_categories][google.cloud.retail.v2.SearchRequest.page_categories].
510  string query = 3;
511
512  // Required. A unique identifier for tracking visitors. For example, this
513  // could be implemented with an HTTP cookie, which should be able to uniquely
514  // identify a visitor on a single device. This unique identifier should not
515  // change if the visitor logs in or out of the website.
516  //
517  // This should be the same identifier as
518  // [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id].
519  //
520  // The field must be a UTF-8 encoded string with a length limit of 128
521  // characters. Otherwise, an INVALID_ARGUMENT error is returned.
522  string visitor_id = 4 [(google.api.field_behavior) = REQUIRED];
523
524  // User information.
525  UserInfo user_info = 5;
526
527  // Maximum number of [Product][google.cloud.retail.v2.Product]s to return. If
528  // unspecified, defaults to a reasonable value. The maximum allowed value is
529  // 120. Values above 120 will be coerced to 120.
530  //
531  // If this field is negative, an INVALID_ARGUMENT is returned.
532  int32 page_size = 7;
533
534  // A page token
535  // [SearchResponse.next_page_token][google.cloud.retail.v2.SearchResponse.next_page_token],
536  // received from a previous
537  // [SearchService.Search][google.cloud.retail.v2.SearchService.Search] call.
538  // Provide this to retrieve the subsequent page.
539  //
540  // When paginating, all other parameters provided to
541  // [SearchService.Search][google.cloud.retail.v2.SearchService.Search] must
542  // match the call that provided the page token. Otherwise, an INVALID_ARGUMENT
543  // error is returned.
544  string page_token = 8;
545
546  // A 0-indexed integer that specifies the current offset (that is, starting
547  // result location, amongst the [Product][google.cloud.retail.v2.Product]s
548  // deemed by the API as relevant) in search results. This field is only
549  // considered if [page_token][google.cloud.retail.v2.SearchRequest.page_token]
550  // is unset.
551  //
552  // If this field is negative, an INVALID_ARGUMENT is returned.
553  int32 offset = 9;
554
555  // The filter syntax consists of an expression language for constructing a
556  // predicate from one or more fields of the products being filtered. Filter
557  // expression is case-sensitive. See more details at this [user
558  // guide](https://cloud.google.com/retail/docs/filter-and-order#filter).
559  //
560  // If this field is unrecognizable, an INVALID_ARGUMENT is returned.
561  string filter = 10;
562
563  // The default filter that is applied when a user performs a search without
564  // checking any filters on the search page.
565  //
566  // The filter applied to every search request when quality improvement such as
567  // query expansion is needed. For example, if a query does not have enough
568  // results, an expanded query with
569  // [SearchRequest.canonical_filter][google.cloud.retail.v2.SearchRequest.canonical_filter]
570  // will be returned as a supplement of the original query. This field is
571  // strongly recommended to achieve high search quality.
572  //
573  // See [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] for
574  // more details about filter syntax.
575  string canonical_filter = 28;
576
577  // The order in which products are returned. Products can be ordered by
578  // a field in an [Product][google.cloud.retail.v2.Product] object. Leave it
579  // unset if ordered by relevance. OrderBy expression is case-sensitive. See
580  // more details at this [user
581  // guide](https://cloud.google.com/retail/docs/filter-and-order#order).
582  //
583  // If this field is unrecognizable, an INVALID_ARGUMENT is returned.
584  string order_by = 11;
585
586  // Facet specifications for faceted search. If empty, no facets are returned.
587  //
588  // A maximum of 200 values are allowed. Otherwise, an INVALID_ARGUMENT error
589  // is returned.
590  repeated FacetSpec facet_specs = 12;
591
592  // Deprecated. Refer to https://cloud.google.com/retail/docs/configs#dynamic
593  // to enable dynamic facets. Do not set this field.
594  //
595  // The specification for dynamically generated facets. Notice that only
596  // textual facets can be dynamically generated.
597  DynamicFacetSpec dynamic_facet_spec = 21 [deprecated = true];
598
599  // Boost specification to boost certain products. See more details at this
600  // [user guide](https://cloud.google.com/retail/docs/boosting).
601  //
602  // Notice that if both
603  // [ServingConfig.boost_control_ids][google.cloud.retail.v2.ServingConfig.boost_control_ids]
604  // and
605  // [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec]
606  // are set, the boost conditions from both places are evaluated. If a search
607  // request matches multiple boost conditions, the final boost score is equal
608  // to the sum of the boost scores from all matched boost conditions.
609  BoostSpec boost_spec = 13;
610
611  // The query expansion specification that specifies the conditions under which
612  // query expansion will occur. See more details at this [user
613  // guide](https://cloud.google.com/retail/docs/result-size#query_expansion).
614  QueryExpansionSpec query_expansion_spec = 14;
615
616  // The keys to fetch and rollup the matching
617  // [variant][google.cloud.retail.v2.Product.Type.VARIANT]
618  // [Product][google.cloud.retail.v2.Product]s attributes,
619  // [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo] or
620  // [LocalInventory][google.cloud.retail.v2.LocalInventory]s attributes. The
621  // attributes from all the matching
622  // [variant][google.cloud.retail.v2.Product.Type.VARIANT]
623  // [Product][google.cloud.retail.v2.Product]s or
624  // [LocalInventory][google.cloud.retail.v2.LocalInventory]s are merged and
625  // de-duplicated. Notice that rollup attributes will lead to extra query
626  // latency. Maximum number of keys is 30.
627  //
628  // For [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], a
629  // fulfillment type and a fulfillment ID must be provided in the format of
630  // "fulfillmentType.fulfillmentId". E.g., in "pickupInStore.store123",
631  // "pickupInStore" is fulfillment type and "store123" is the store ID.
632  //
633  // Supported keys are:
634  //
635  // * colorFamilies
636  // * price
637  // * originalPrice
638  // * discount
639  // * variantId
640  // * inventory(place_id,price)
641  // * inventory(place_id,original_price)
642  // * inventory(place_id,attributes.key), where key is any key in the
643  //   [Product.local_inventories.attributes][google.cloud.retail.v2.LocalInventory.attributes]
644  //   map.
645  // * attributes.key, where key is any key in the
646  //   [Product.attributes][google.cloud.retail.v2.Product.attributes] map.
647  // * pickupInStore.id, where id is any
648  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
649  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
650  //   "pickup-in-store".
651  // * shipToStore.id, where id is any
652  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
653  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
654  //   "ship-to-store".
655  // * sameDayDelivery.id, where id is any
656  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
657  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
658  //   "same-day-delivery".
659  // * nextDayDelivery.id, where id is any
660  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
661  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
662  //   "next-day-delivery".
663  // * customFulfillment1.id, where id is any
664  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
665  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
666  //   "custom-type-1".
667  // * customFulfillment2.id, where id is any
668  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
669  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
670  //   "custom-type-2".
671  // * customFulfillment3.id, where id is any
672  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
673  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
674  //   "custom-type-3".
675  // * customFulfillment4.id, where id is any
676  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
677  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
678  //   "custom-type-4".
679  // * customFulfillment5.id, where id is any
680  // [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]
681  // for [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]
682  //   "custom-type-5".
683  //
684  // If this field is set to an invalid value other than these, an
685  // INVALID_ARGUMENT error is returned.
686  repeated string variant_rollup_keys = 17;
687
688  // The categories associated with a category page. Required for category
689  // navigation queries to achieve good search quality. The format should be
690  // the same as
691  // [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories];
692  //
693  // To represent full path of category, use '>' sign to separate different
694  // hierarchies. If '>' is part of the category name, replace it with
695  // other character(s).
696  //
697  // Category pages include special pages such as sales or promotions. For
698  // instance, a special sale page may have the category hierarchy:
699  // "pageCategories" : ["Sales > 2017 Black Friday Deals"].
700  repeated string page_categories = 23;
701
702  // The search mode of the search request. If not specified, a single search
703  // request triggers both product search and faceted search.
704  SearchMode search_mode = 31;
705
706  // The specification for personalization.
707  //
708  // Notice that if both
709  // [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec]
710  // and
711  // [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
712  // are set.
713  // [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec]
714  // will override
715  // [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec].
716  PersonalizationSpec personalization_spec = 32;
717
718  // The labels applied to a resource must meet the following requirements:
719  //
720  // * Each resource can have multiple labels, up to a maximum of 64.
721  // * Each label must be a key-value pair.
722  // * Keys have a minimum length of 1 character and a maximum length of 63
723  //   characters and cannot be empty. Values can be empty and have a maximum
724  //   length of 63 characters.
725  // * Keys and values can contain only lowercase letters, numeric characters,
726  //   underscores, and dashes. All characters must use UTF-8 encoding, and
727  //   international characters are allowed.
728  // * The key portion of a label must be unique. However, you can use the same
729  //   key with multiple resources.
730  // * Keys must start with a lowercase letter or international character.
731  //
732  // See [Google Cloud
733  // Document](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements)
734  // for more details.
735  map<string, string> labels = 34;
736
737  // The spell correction specification that specifies the mode under
738  // which spell correction will take effect.
739  optional SpellCorrectionSpec spell_correction_spec = 35;
740
741  // The entity for customers that may run multiple different entities, domains,
742  // sites or regions, for example, `Google US`, `Google Ads`, `Waymo`,
743  // `google.com`, `youtube.com`, etc.
744  // If this is set, it should be exactly matched with
745  // [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] to get search
746  // results boosted by entity.
747  string entity = 38;
748}
749
750// Response message for
751// [SearchService.Search][google.cloud.retail.v2.SearchService.Search] method.
752message SearchResponse {
753  // Represents the search results.
754  message SearchResult {
755    // [Product.id][google.cloud.retail.v2.Product.id] of the searched
756    // [Product][google.cloud.retail.v2.Product].
757    string id = 1;
758
759    // The product data snippet in the search response. Only
760    // [Product.name][google.cloud.retail.v2.Product.name] is guaranteed to be
761    // populated.
762    //
763    // [Product.variants][google.cloud.retail.v2.Product.variants] contains the
764    // product variants that match the search query. If there are multiple
765    // product variants matching the query, top 5 most relevant product variants
766    // are returned and ordered by relevancy.
767    //
768    // If relevancy can be deternmined, use
769    // [matching_variant_fields][google.cloud.retail.v2.SearchResponse.SearchResult.matching_variant_fields]
770    // to look up matched product variants fields. If relevancy cannot be
771    // determined, e.g. when searching "shoe" all products in a shoe product can
772    // be a match, 5 product variants are returned but order is meaningless.
773    Product product = 2;
774
775    // The count of matched
776    // [variant][google.cloud.retail.v2.Product.Type.VARIANT]
777    // [Product][google.cloud.retail.v2.Product]s.
778    int32 matching_variant_count = 3;
779
780    // If a [variant][google.cloud.retail.v2.Product.Type.VARIANT]
781    // [Product][google.cloud.retail.v2.Product] matches the search query, this
782    // map indicates which [Product][google.cloud.retail.v2.Product] fields are
783    // matched. The key is the
784    // [Product.name][google.cloud.retail.v2.Product.name], the value is a field
785    // mask of the matched [Product][google.cloud.retail.v2.Product] fields. If
786    // matched attributes cannot be determined, this map will be empty.
787    //
788    // For example, a key "sku1" with field mask
789    // "products.color_info" indicates there is a match between
790    // "sku1" [ColorInfo][google.cloud.retail.v2.ColorInfo] and the query.
791    map<string, google.protobuf.FieldMask> matching_variant_fields = 4;
792
793    // The rollup matching
794    // [variant][google.cloud.retail.v2.Product.Type.VARIANT]
795    // [Product][google.cloud.retail.v2.Product] attributes. The key is one of
796    // the
797    // [SearchRequest.variant_rollup_keys][google.cloud.retail.v2.SearchRequest.variant_rollup_keys].
798    // The values are the merged and de-duplicated
799    // [Product][google.cloud.retail.v2.Product] attributes. Notice that the
800    // rollup values are respect filter. For example, when filtering by
801    // "colorFamilies:ANY(\"red\")" and rollup "colorFamilies", only "red" is
802    // returned.
803    //
804    // For textual and numerical attributes, the rollup values is a list of
805    // string or double values with type
806    // [google.protobuf.ListValue][google.protobuf.ListValue]. For example, if
807    // there are two variants with colors "red" and "blue", the rollup values
808    // are
809    //
810    //     { key: "colorFamilies"
811    //       value {
812    //         list_value {
813    //           values { string_value: "red" }
814    //           values { string_value: "blue" }
815    //          }
816    //       }
817    //     }
818    //
819    // For [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], the rollup
820    // values is a double value with type
821    // [google.protobuf.Value][google.protobuf.Value]. For example,
822    // `{key: "pickupInStore.store1" value { number_value: 10 }}` means a there
823    // are 10 variants in this product are available in the store "store1".
824    map<string, google.protobuf.Value> variant_rollup_values = 5;
825
826    // Specifies previous events related to this product for this user based on
827    // [UserEvent][google.cloud.retail.v2.UserEvent] with same
828    // [SearchRequest.visitor_id][google.cloud.retail.v2.SearchRequest.visitor_id]
829    // or [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id].
830    //
831    // This is set only when
832    // [SearchRequest.PersonalizationSpec.mode][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.mode]
833    // is
834    // [SearchRequest.PersonalizationSpec.Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO].
835    //
836    // Possible values:
837    //
838    // * `purchased`: Indicates that this product has been purchased before.
839    repeated string personal_labels = 7;
840  }
841
842  // A facet result.
843  message Facet {
844    // A facet value which contains value names and their count.
845    message FacetValue {
846      // A facet value which contains values.
847      oneof facet_value {
848        // Text value of a facet, such as "Black" for facet "colorFamilies".
849        string value = 1;
850
851        // Interval value for a facet, such as [10, 20) for facet "price".
852        Interval interval = 2;
853      }
854
855      // Number of items that have this facet value.
856      int64 count = 3;
857
858      // The minimum value in the
859      // [FacetValue.interval][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval].
860      // Only supported on numerical facets and returned if
861      // [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max]
862      // is true.
863      double min_value = 5;
864
865      // The maximum value in the
866      // [FacetValue.interval][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval].
867      // Only supported on numerical facets and returned if
868      // [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max]
869      // is true.
870      double max_value = 6;
871    }
872
873    // The key for this facet. E.g., "colorFamilies" or "price" or
874    // "attributes.attr1".
875    string key = 1;
876
877    // The facet values for this field.
878    repeated FacetValue values = 2;
879
880    // Whether the facet is dynamically generated.
881    bool dynamic_facet = 3;
882  }
883
884  // Information describing query expansion including whether expansion has
885  // occurred.
886  message QueryExpansionInfo {
887    // Bool describing whether query expansion has occurred.
888    bool expanded_query = 1;
889
890    // Number of pinned results. This field will only be set when expansion
891    // happens and
892    // [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.pin_unexpanded_results]
893    // is set to true.
894    int64 pinned_result_count = 2;
895  }
896
897  // A list of matched items. The order represents the ranking.
898  repeated SearchResult results = 1;
899
900  // Results of facets requested by user.
901  repeated Facet facets = 2;
902
903  // The estimated total count of matched items irrespective of pagination. The
904  // count of [results][google.cloud.retail.v2.SearchResponse.results] returned
905  // by pagination may be less than the
906  // [total_size][google.cloud.retail.v2.SearchResponse.total_size] that
907  // matches.
908  int32 total_size = 3;
909
910  // Contains the spell corrected query, if found. If the spell correction type
911  // is AUTOMATIC, then the search results are based on corrected_query.
912  // Otherwise the original query is used for search.
913  string corrected_query = 4;
914
915  // A unique search token. This should be included in the
916  // [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting from this
917  // search, which enables accurate attribution of search model performance.
918  string attribution_token = 5;
919
920  // A token that can be sent as
921  // [SearchRequest.page_token][google.cloud.retail.v2.SearchRequest.page_token]
922  // to retrieve the next page. If this field is omitted, there are no
923  // subsequent pages.
924  string next_page_token = 6;
925
926  // Query expansion information for the returned results.
927  QueryExpansionInfo query_expansion_info = 7;
928
929  // The URI of a customer-defined redirect page. If redirect action is
930  // triggered, no search is performed, and only
931  // [redirect_uri][google.cloud.retail.v2.SearchResponse.redirect_uri] and
932  // [attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token]
933  // are set in the response.
934  string redirect_uri = 10;
935
936  // The fully qualified resource name of applied
937  // [controls](https://cloud.google.com/retail/docs/serving-control-rules).
938  repeated string applied_controls = 12;
939
940  // The invalid
941  // [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs]
942  // that are not applied during serving.
943  repeated SearchRequest.BoostSpec.ConditionBoostSpec
944      invalid_condition_boost_specs = 14;
945
946  // Metadata related to A/B testing [Experiment][] associated with this
947  // response. Only exists when an experiment is triggered.
948  repeated ExperimentInfo experiment_info = 17;
949}
950
951// Metadata for active A/B testing [Experiments][].
952message ExperimentInfo {
953  // Metadata for active serving config A/B tests.
954  message ServingConfigExperiment {
955    // The fully qualified resource name of the original
956    // [SearchRequest.placement][google.cloud.retail.v2.SearchRequest.placement]
957    // in the search request prior to reassignment by experiment API. For
958    // example: `projects/*/locations/*/catalogs/*/servingConfigs/*`.
959    string original_serving_config = 1 [(google.api.resource_reference) = {
960      type: "retail.googleapis.com/ServingConfig"
961    }];
962
963    // The fully qualified resource name of the serving config
964    // [VariantArm.serving_config_id][] responsible for generating the search
965    // response. For example:
966    // `projects/*/locations/*/catalogs/*/servingConfigs/*`.
967    string experiment_serving_config = 2 [(google.api.resource_reference) = {
968      type: "retail.googleapis.com/ServingConfig"
969    }];
970  }
971
972  // Information associated with the specific experiment entity being recorded.
973  oneof experiment_metadata {
974    // A/B test between existing Cloud Retail Search
975    // [ServingConfig][google.cloud.retail.v2.ServingConfig]s.
976    ServingConfigExperiment serving_config_experiment = 2;
977  }
978
979  // The fully qualified resource name of the experiment that provides the
980  // serving config under test, should an active experiment exist. For example:
981  // `projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`
982  string experiment = 1 [(google.api.resource_reference) = {
983    type: "retail.googleapis.com/Experiment"
984  }];
985}
986