Index and Query Popular Searches

Oracle Commerce offers a ready-to-use typeahead function, which searches against and returns product records. This can be used to display products, their prices, images, and so on

Typeahead enables shoppers to also search against other popular search terms. It comes with pre-configured APIs and schema. You need to provide your own search terms and handle rendering the results from this endpoint.

To provide an alternative type-ahead experience for shoppers, you can configure Commerce to search against terms that it has automatically identified as popular with other shoppers. Additionally, Commerce can also search against your own custom or curated search terms.

You must implement this feature using the REST APIs. Commerce widgets do not support this feature by default. To use this feature, you must ensure that you are using the correct configuration, and handle rendering the results from this endpoint. Perform the following steps to use this feature:

  • Index popular searches records
  • Query the correct endpoint

Note: Popular searches are automatically generated only in production and live environments.

Index popular searches records

Each term that can appear in the results for a query against popular searches is a single record. If you have a list of 15,000 popular search terms, each term is a separate record and indexed separately.

For each record, there are four required fields:

  • record.id
  • keyword.terms
  • keyword.searchable
  • keyword.score

Shopper searches are normally matched against the keyword.searchable field, which may contain synonym forms, common misspellings, or any other “alternative” forms of the term corresponding to a given record. The keyword.terms field contains the canonical form of the term and is the one normally displayed in the results and searched for when the result is selected.

Ensure that all the fields above are properly configured by submitting the following POST request:

POST /gsadmin/v1/cloud/attributes/keywords
{
  "ecr:type": "attributes-owner-folder",
  "keyword.terms": {
    "ecr:type": "property",
    "propertyDataType": "ALPHA",
    "isRecordSearchEnabled": false,
    "isWildcardEnabledInRecordSearch": false,
    "context": [ "locale" ]
  },
  "keyword.searchable": {
    "ecr:type": "property",
    "propertyDataType": "ALPHA",
    "isRecordSearchEnabled": true,
    "isWildcardEnabledInRecordSearch": true,
    "context": [ "locale" ]
  },
  "keyword.score": {
    "ecr:type": "property",
    "propertyDataType": "DOUBLE"
  },
  "keyword.searchCount": {
    "ecr:type": "property",
    "propertyDataType": "INTEGER"
  }
}

Suppress product names as suggestions

In all environments, product names are included in the search suggestions to provide a "cold start" for newly launched sites. You may prefer to switch this off. To do so, call the API endpoint /gsadmin/v1/cloud/configuration/services/internal-keywords and change the property gsdataCatalogLimit to 1.

Automatic popular searches records

Commerce automatically identifies popular searches based on shoppers’ past behavior, and periodically uploads the corresponding records to the internal-keywords record collection. From there, they are processed for indexing. The contents of the internal-keywords record collection at any given time can be inspected by querying the following endpoint:

GET /gsdata/v1/cloud/data/internal-keywords

Important: Do not attempt to modify the internal-keywords record collection. Your changes will be overwritten.

Preview popular searches in non-live environments

Should you wish to preview the search suggestions from a Live environment in a lower environment, you can temporarily migrate the search suggestions to a lower environment by performing the following steps:
  1. Issue a DELETE command to /gsdata/v1/cloud/data/internal-keywords on the DEV / TEST environment to remove any existing data (if necessary).
  2. Issue a GET command to /gsdata/v1/cloud/data/internal-keywords on the LIVE environment to retrieve the production data.
  3. Issue a POST command to /gsdata/v1/cloud/data/internal-keywords on the DEV / TEST environment with the retrieved production data.
Doing this will copy the production suggestions to the targeted environment. Note that this is a temporary operation. Should you wish to see the latest suggestions, you will need to perform the above steps again.

Add your own custom keyword records

To add custom keyword records to the system so they can be processed for indexing, you must upload them to the keywords record collection with the following endpoint:

POST /gsdata/v1/cloud/data/keywords

Multiple records can be submitted in each request. Multiple requests can be made to add data. That is, subsequent POST calls to /gsdata will not replace previously submitted records. If you need to submit a large number of records, it is recommended to submit then in a few sets, rather than one at a time.

The following is a sample POST command that submits three records using the above schema:

POST /gsdata/v1/cloud/data/keywords
{
  "items":[
   {
    "record.id": "kw-en:digital+cameras",
    "keyword.terms@locale:en": "digital cameras",
    "keyword.searchable@locale:en": [
      "digital cameras", "digicams"
    ],
    "keyword.score": "12234"
   },
   {
    "record.id": "kw-en:film+cameras",
    "keyword.terms@locale:en": "film cameras",
    "keyword.searchable@locale:en": "film cameras",
    "keyword.score": "3234"
   },
   {
    "record.id":"kw-en:dslr+cameras",
    "keyword.terms@locale:en": "dslr cameras",
    "keyword.searchable@locale:en": [
      "dslr cameras", "digital slr cameras", "slr digicams"
    ],
    "keyword.score": "23421"
   }
  ]
}

Localize the custom keyword records

The fields keyword.terms and keyword.searchable in the previous section are localized. When uploading records, you must specify the correct locale (for example, @locale:en for English) that shoppers will search under.

Each keyword record can optionally contain translations for multiple locales. It is perfectly acceptable to create multiple, single-locale keyword records for multiple locales. For example:

POST /gsdata/v1/cloud/data/keywords
{
  "items":[
   {
    "record.id": "kw-en:book",
    "keyword.terms@locale:en": "book",
    "keyword.searchable@locale:en": "book",
    "keyword.score": "1"
   },
   {
    "record.id": "kw-fr:livre",
    "keyword.terms@locale:fr": "livre",
    "keyword.searchable@locale:fr": "livre",
    "keyword.score": "1"
   },
   {
    "record.id": "kw:notebook",
    "keyword.terms@locale:en": "notebook",
    "keyword.searchable@locale:en": "notebook",
    "keyword.terms@locale:fr": "cahier",
    "keyword.searchable@locale:fr": "cahier",
    "keyword.score": "1"
   }
]
}

Index additional fields for custom keyword records

You may want to return additional information with your custom keyword records. In this case, you can add custom fields. There is no fixed schema for those additional fields, but it is recommended that you follow the naming convention of keyword.x. For example, keyword.related_terms, or keyword.related_product_id. For more information, see Modify the configuration to return additional fields.

Perform indexing

If you added custom keyword records to the system and defined schema, you need to run the search indexing process. To do so, use the following API call. Keep in mind that indexing times will vary depending on the size of your catalog.

POST /ccadmin/v1/search/index {"op":"baseline" }

Query the keywords endpoint

At this point, your popular search records are available in the index.

Ensure that the search service definition is properly configured by using the following endpoints:

POST /gsadmin/v1/cloud/searchInterfaces/keywords
{
  "isAutoWildcardEnabled": true,
  "ecr:type": "search-interface",
  "crossFieldMatch": "never",
  "fields": [
    {
      "attribute": "keyword.searchable"
    }
  ]
}

POST /gsadmin/v1/cloud/pages/Default/keywords/typeahead
{
  "contentType": "Page",
  "ecr:type": "page",
  "contentItem": {
    "@name": "Keyword Search Service",
    "@type": "KeywordSearchService",
    "@appFilterState": {
      "@type": "FilterState",
      "typeAhead": true,
      "recordFilters": [
        "OR(record.collection:keywords,record.collection:internal-keywords)"
      ]
    },
    "resultsList": {
      "@type": "ResultsList",
      "relRankStrategy": "static(keyword.score,descending)",
      "fieldNames": [
        "record.id",
        "keyword.terms",
        "keyword.score"
      ]
    }
  }
}

Run the following endpoint:

GET /ccstore/v1/assembler/pages/Default/keywords/typeahead

and specify the following two parameters to perform a search:

  • Ntt= This is the user’s search terms. For instance, if the customer has typed “cam” as part of searching for “camera”, you would set it to &Ntt=cam
  • Ntk= This specifies the search key. A search interface named “keywords” has been defined

For example:

GET /ccstore/v1/assembler/pages/Default/keywords/typeahead?Ntt=cam&Ntk=keywords

Modify the configuration to return additional fields

In order to provide a responsive service that is also quite small in size, the default /keywords/typeahead service is configured only to return a minimal set of fields in the resultsList.

If you want additional fields returned, you must modify the /keywords/typeahead service:

  1. Run GET /gsadmin/v1/cloud/pages/Default/keywords/typeahead.
  2. Add the custom fields to the list of fieldNames.
  3. PUT the modifications back to /gsadmin/v1/cloud/pages/Default/keywords/typeahead.

Configure typeahead query prefixes

By default, Commerce ignores typeahead and wildcard search terms of less than 2 characters.

If you want to change the default behavior, you can use the Search Interfaces endpoints in the Search Admin and Configuration API to change the value of the minWildcardWordLength search configuration property. For example, if you set the property value to zero (0), the search begins as soon as the shopper types a character.

Keep in mind that setting the value of minWildcardWordLength to less than the default value (2) might impact performance.

Note that the minWildcardWordLength search configuration property does not apply to dimension search or compound dimension search, or to the Chinese, Japanese, or Korean languages.

The following sample shows how you can set the value of minWildcardWordLength to 0 for typeahead and wildcard searches.

PUT /gsadmin/v1/cloud/searchInterfaces/TypeAhead 
{
  "ecr:type": "search-interface",
  "crossFieldMatch": "always",
  "isAutoWildcardEnabled": true,
  "minWildcardWordLength": 0, 
  "fields": [
    {
      "attribute": "product.displayName"
    },
    {
      "attribute": "ecr:crossField"
    },
    {
      "attribute": "product.category"
    }
  ]
}