Configure serving controls for search

Serving controls (also called controls) change the default behavior of a request.

For example, controls can boost and bury results, filter entries from returned results, associate queries with each other as synonyms, or redirect queries to specified URIs.

This page describes serving controls for search apps. For information about using serving controls with media recommendations, see Create and manage serving configs.

About serving controls

To change the results of a request, first create a serving control. Then, attach that control to an app. A control only affects requests served by an app that the control is attached to. If a control isn't attached to an app, it has no effect.

Some controls, such as boost controls, have dependencies on data stores. If a data store is removed from an app, then any data store-dependent controls are also removed from that app and become inactive, but are not deleted.

When creating a control, you can optionally define a condition that determines when the control is applied. Conditions are defined using condition fields. The following condition fields are available:

  • queryTerms. The control is applied when specific queries are searched for.
  • activeTimeRange. The control is applied when a request occurs within a specified time range.

If both types of conditions are specified for a control, the control is applied to the search request when both condition types are satisfied. If multiple values for the same condition are specified, only one of the values needs to match for that condition to be satisfied.

For example, consider the following condition with two query terms specified:

"queryTerms": [
  {
    "value": "gShoe",
    "fullMatch": true
  },
  {
    "value": "gBoot",
    "fullMatch": true
  }
]

The condition will be satisfied for a request with SearchRequest.query="gShoe" or a request with SearchRequest.query="gBoot", but won't be satisfied with SearchRequest.query="gSandal" or any other string.

If no conditions are specified, the control is always applied.

For more information, see servingConfigs.search in the API reference.

Serving control types

The following types of serving controls are available:

Control Description Available for
Boost control Changes the returned order of results Search apps with data stores that support a schema, such as data stores that contain structured data, websites with structured data, unstructured data with metadata, or media data
Filter control Removes entries from returned results Search apps with data stores that support a schema, such as data stores that contain structured data, websites with structured data, unstructured data with metadata, or media data
Synonyms control Associates queries with each other Search apps with website, structured, unstructured, or media data stores
Redirect control Redirects to a specified URI All search apps

About boost serving controls

A boost serving control is defined as a control with a boostAction.

The syntax for a boostAction is as follows:

{
    "boost": "BOOST",
    "filter": "FILTER",
    "dataStore": "DATA_STORE_RESOURCE_PATH"
}
  • BOOST: A float between -1 and 1. When the value is negative, results are demoted to appear later in search results. When the value is positive results are promoted to appear earlier in search results.
  • FILTER: A string specifying requirements that must be met by the document. If the document matches all the requirements, the boost is applied. Otherwise there is no change. If this field is empty, then the boost is applied to all documents in the data store. For the filtering syntax, see Filter expression syntax.
  • DATA_STORE_RESOURCE_PATH: The full resource path of the data store whose documents should be boosted by this control. The format of the full resource path is projects/PROJECT_ID/locations/LOCATION_ID/collections/default_collection/dataStores/DATA_STORE_ID. This data store must be attached to the engine specified in the request.

About filter serving controls

A filter serving control is defined as a control with a filterAction.

The syntax for a filterAction is as follows:

{
    "filter": "FILTER"
}
  • FILTER: A string specifying requirements that must be met by the document. If the document matches all the requirements, the result is included in the result list. Otherwise, the result is removed from the result list. For the filtering syntax, see Filter expression syntax.

About synonyms serving controls

A synonyms serving control is defined as a control with a synonymsAction.

The syntax for a synonymsAction is as follows:

{
    "synonyms": "SYNONYMS"
}
  • SYNONYMS: Strings that will be associated with each other, making it more likely for each to show similar results. You must specify at least two strings, and you can specify up to 100 strings. Strings must be UTF-8 and lowercase. No duplicate strings are allowed.

For example:

{
    "synonyms": ["pixel", "android phone", "google phone"]
}

About redirect serving controls

A redirect serving control allows redirecting users to a provided URI.

Redirect controls are defined as a control with a redirectAction.

Syntax for redirectAction:

{
    "redirect_uri": "REDIRECT_URI"
}
  • REDIRECT_URI: A URI of at most 2000 characters.

For example, if the value of the query term is "support", you can set a redirect to your technical support page instead of returning (or failing to return) search results for "support".

{
    "redirect_uri": ["https://www.example.com/support"]
}

About the queryTerms condition

queryTerms is optional. Use it if you want a serving control to be used when specific queries are searched for. When the queryTerms condition is used, the control is applied when the value of queryTerms matches a term in SearchRequest.query.

Query terms can only be used when the Control.searchUseCase is set as SOLUTION_TYPE_SEARCH.

Up to 10 different queryTerms can be specified on a single Control.condition. If no query terms are specified, the field is ignored.

The syntax for a single queryTerm is as follows:

{
    "value": "VALUE_1",
    "fullMatch": "FULL_MATCH_1"
}
  • VALUE_1: A lowercase UTF-8 string with length [1, 5000]. If FULL_MATCH_1 is true, it can have at most three space-separated terms.
  • FULL_MATCH_1: A boolean. When set to true, it requires SearchRequest.query to completely match the queryTerm.value. When set to false, it requires SearchRequest.query to contain queryTerm.value as a substring.

About the activeTimeRange condition

activeTimeRange is optional. It checks that the time a request was received is between activeTimeRange.startTime and activeTimeRange.endTime.

Up to 10 activeTimeRange ranges can be specified on a single Control.condition. If no activeTimeRange ranges are specified, the field is ignored.

The syntax for a single activeTimeRange is as follows:

[
  {
    "startTime": "START_TIMESTAMP_1",
    "endTime": "END_TIMESTAMP_1"
  }
]
  • START_TIMESTAMP_1: Defines the earliest time (inclusive) that the control will be applied. Timestamps are in RFC 3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits—for example, "2023-10-02T15:01:23Z".
  • END_TIMESTAMP_1: Defines the latest time (inclusive) that the control will be applied. This time must be in the future.

API instructions: Change default search request behavior with serving controls

To change the default search request behavior, you create a serving control and attach it to the default serving config.

Before you begin

If you want to create serving controls, contact your Google account team and ask to be added to the allowlist for serving controls.

Create a serving control

Use the following instructions to create a serving control.

For field details, see the Controls API reference and the Controls.create API reference.

  1. Find your data store ID. If you already have your data store ID, skip to the next step.

    1. In the Google Cloud console, go to the Agent Builder page and in the navigation menu, click Data Stores.

      Go to the Data Stores page

    2. Click the name of your data store.

    3. On the Data page for your data store, get the data store ID.

  2. Choose the condition type and field values for your control.

    The following is a truncated example of a condition:

    {
      "queryTerms": [
          {
            "value": "VALUE_1",
            "fullMatch": FULL_MATCH_1
          },
          {
            "value": "VALUE_2",
            "fullMatch": FULL_MATCH_2
          },
        ],
      "activeTimeRange": [
        {
          "startTime": "START_TIMESTAMP_1",
          "endTime": "END_TIMESTAMP_1"
        },
        {
          "startTime": "START_TIMESTAMP_2",
          "endTime": "END_TIMESTAMP_2"
        },
      ]
    }
    
  3. Run the following curl commands to create your controls.

    Boost control: Click to see the curl command to create a boost control.

    Run the following curl command:

        curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/controls?CONTROL_ID" \
        -d '{
        "displayName": "DISPLAY_NAME",
        "solutionType": "SOLUTION_TYPE_SEARCH",
        "useCases": ["USE_CASE"],
        "conditions": ["CONDITION"],
        "boostAction": "BOOST_ACTION",
        }'

    Filter control: Click to see the curl command to create a filter control.

    Run the following curl command:

        curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/controls?controlId=CONTROL_ID" \
        -d '{
        "displayName": "DISPLAY_NAME",
        "solutionType": "SOLUTION_TYPE_SEARCH",
        "useCases": ["USE_CASE"],
        "conditions": ["CONDITION"],
        "filterAction": "FILTER_ACTION",
        }'

    Synonyms control: Click to see the curl command to create a synonyms control.

    Run the following curl command:

        curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/controls?controlId=CONTROL_ID" \
        -d '{
        "displayName": "DISPLAY_NAME",
        "solutionType": "SOLUTION_TYPE_SEARCH",
        "useCases": ["USE_CASE"],
        "conditions": ["CONDITION"],
        "synonymsAction": "SYNONYMS_ACTION",
        }'

    Redirect control: Click to see the curl command to create a redirect control.

    Run the following curl command:

        curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/controls?controlId=CONTROL_ID" \
        -d '{
        "displayName": "DISPLAY_NAME",
        "solutionType": "SOLUTION_TYPE_SEARCH",
        "useCases": ["USE_CASE"],
        "conditions": ["CONDITION"],
        "redirectAction": "REDIRECT_ACTION",
        }'
    • PROJECT_ID: The project number or ID of your Google Cloud project.
    • DATA_STORE_ID: The unique ID of the data store.
    • CONTROL_ID: A unique identifier (within a data store) for the control. The ID can contain lowercase letters, digits, hyphens, and underscores.
    • DISPLAY_NAME: The human-readable name for the control. Google recommends that this name provide an indication of when or why to use the control. Must be a UTF-8 string with length [1,128].
    • USE_CASE: Must be either SEARCH_USE_CASE_SEARCH or SEARCH_USE_CASE_BROWSE. If SEARCH_USE_CASE_BROWSE is specified, then Condition.queryTerms can't be used in the condition.
    • CONDITION: (Optional) Defines when the control should be applied.
    • BOOST_ACTION: Used to define a boost control. See the boostAction API reference.
    • FILTER_ACTION: Used to define a filter control. See the filterAction API reference.
    • SYNONYMS_ACTION: Used to define a synonyms control. See the synonymsAction API reference.
    • REDIRECT_ACTION: Used to specify a redirection URI. See the redirectAction API reference.
  4. Attach the control to the app.

    Boost control: Click for the curl command for a boost control.

    Run the following curl command to attach a boost control to a serving configuration to enable use on serving requests:

        curl -X PATCH -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/servingConfigs/default_search?update_mask=boost_control_ids" \
        -d '{
          "boostControlIds": ["BOOST_ID_1", "BOOST_ID_2" … ]
        }'

    BOOST_ID_1 and BOOST_ID_2: Represent the control IDs that you created in the previous step.

    Filter control: Click the curl command for a filter control.

    Run the following curl command to attach a filter control to a serving configuration to enable use on serving requests:

        curl -X PATCH -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/servingConfigs/default_search?update_mask=filter_control_ids" \
        -d '{
          "filterControlIds": ["FILTER_ID_1", "FILTER_ID_2" … ]
        }'

    FILTER_ID_1 and FILTER_ID_2: Represent the control IDs that you created in the previous step.

    Synonyms control: Click for the curl command for a synonyms control.

    Run the following curl command to attach a synonyms control to an app to enable use on serving requests:

        curl -X PATCH -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/servingConfigs/default_search?update_mask=synonyms_control_ids" \
        -d '{
         "synonymsControlIds": ["SYNONYM_ID_1", "SYNONYM_ID_2" … ]
        }'

    SYNONYM_ID_1 and SYNONYM_ID_2: Represent the control IDs that you created in the previous step.

    Redirect control: Click for the curl command for a redirect control.

    Run the following curl command to attach a redirect control to an app to enable use on serving requests:

        curl -X PATCH
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "X-Goog-User-Project: PROJECT_ID" \
        "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores/DATA_STORE_ID/servingConfigs/default_search?update_mask=redirect_control_ids" \
        -d '{
          "redirectControlIds": ["REDIRECT_ID_1", "REDIRECT_ID_2" … ]
        }'

    REDIRECT_ID_1 and REDIRECT_ID_2: Represent the control IDs that you created in the previous step.

What's next

  • To understand the impact of a serving control on the search quality of a generic search app, evaluate the search quality. For more information, see Evaluate search quality.