Implement a result list

This is for:

Developer

A search interface almost always displays a list of results which the user can use to interact with query result items. This article provides guidelines for implementing a result list on your own, assuming that you can’t use the Coveo Atomic or Headless libraries in your custom search integration with the Coveo Platform.

Note

As a reference, you may want to look at the source code of the ResultList component to see how it’s implemented in the Coveo JavaScript Search Framework.

Standard result list actions

The following table lists some actions that you may want to make available in a result list implementation.

Each entry indicates the specific Coveo Usage Analytics (Coveo UA) event category, actionCause or eventValue, eventType, and customData that must be logged when the action is performed, as well as a link to the corresponding implementation guidelines.

Result list action UA events actionCause eventType eventValue customData Implementation guidelines

Click a result

Click

documentOpen

N/A

N/A

author, contentIdKey, contentIdValue, documentTitle, documentURL

Open query results

Click a recommendation

Click

recommendationOpen

N/A

N/A

author, contentIdKey, contentIdValue, documentTitle, documentURL

Open query results

Preview a result

Click

documentQuickview

N/A

N/A

author, contentIdKey, contentIdValue, documentTitle, documentURL

Preview a result

Select a page of results

Custom

N/A

getMoreResults

pagerNumber

pagerNumber

Page query results

Select the next page of results

Custom

N/A

getMoreResults

pagerNumber

pagerNext

Page query results

Select the previous page of results

Custom

N/A

getMoreResults

pagerNumber

pagerPrevious

Page query results

Scroll to get more results in infinite scroll mode

Custom

N/A

getMoreResults

pagerNumber

pagerScrolling

Page query results

Resize the number of results per page

Custom

N/A

getMoreResults

pagerResize

currentResultsPerPage

Page query results

Sort results

Search

resultsSort

N/A

N/A

resultsSortBy

Sort query results

Change the result layout

Custom

N/A

resultsLayout

changeResultsLayout

resultsLayoutChangeTo

Switch result list layouts

Export to Excel

Custom

N/A

misc

exportToExcel

N/A

Export results

Toggle a facet from a result list item

Search

documentField

N/A

N/A

facetField, facetId, facetValue

Toggle a facet value from a result list item

Note

It’s important to use the proper eventType, actionCause or eventValue, and customData when logging a UA event for a specific type of action in a search interface. Otherwise:

Render query results

You typically want to update the result list whenever a search request to the Search API returns.

The results array of a query response contains the list of query result items which you typically rely on to render or update the result list. By default, the results array is sorted by relevance (that is, by descending index ranking score value), but you can modify this behavior using the sortCriteria search request parameter.

Note

In a search interface with many similar results, you may want use the enableDuplicateFiltering search request parameter. Result items are considered duplicates when the proportion of their data that’s identical exceeds a certain threshold. When enableDuplicateFiltering is set to true and some items are duplicates, only one of those items will appear in the results array of the query response.

Duplicate filtering and result folding are mutually exclusive.

The following properties are especially useful when rendering a query result item:

  • Descriptions:

    • title: The title of the item. Use this to render the item in the result list. This property should be saved, as its value will be required when logging a UA click event for the item.

    • excerpt: Text segments from the item, generated using query keywords. You can set the maximum length (in number of characters, 200 by default) using the excerptLength parameter in the search request.

    • firstSentences: The first sentences of the item. This property won’t be populated unless the retrieveFirstSentences parameter is set to true in the search request. You can set the maximum length (in number of characters, 200 by default) using the excerptLength parameter in the search request.

    • summary: A description of the item, generated independently of query keywords. You can set the maximum length (in number of characters, 0 by default) using the summaryLength parameter in the search request.

    • printableUri: A human-readable version of the item URI to be displayed.

  • Highlights:

    All of the preceding properties have a <propertyName>Highlights counterpart which contains an array of {length, offset} elements. Each of these elements indicates a keyword to highlight (for example, using bold or italic text) when rendering the corresponding value.

    • titleHighlights

    • excerptHighlights

    • firstSentencesHighlights

    • summaryHighlights

    • printableUriHighlights

  • Link:

    • clickUri: The hyperlinkable item URI. Use this to define the target when rendering a link to the corresponding item (for example, as the value of the href attribute in an HTML anchor element).

  • fields:

    The raw property of a query result item contains key-value pairs, each corresponding to the name of a field along with its value for that specific item. The following fields are particularly important, and they should be included as customData (if available) when logging UA click events for that item:

    • author: The author of the item.

    • permanentid: The unique identifier of the item in the index.

    Notes
    • By default, values in multi-value fields are separated by semicolon characters. For example, an item that corresponds to the coauthored book The Talisman may have the following key-value pair: "authors":"Stephen King;Peter Straub".

    • When performing queries, you can take advantage of the fieldsToInclude or fieldsToExclude search request parameters to only request the fields which are required by your search interface. By default, all fields are requested, which is typically non-optimal.

  • Miscellaneous:

    • uri: The URI of the item. Although you won’t typically use this to render the item in the result list, this property should be saved, as its value will be required when logging a UA click event for the item.

    • isRecommendation: Whether the query result item was recommended by a Coveo ML Automatic Relevance Tuning (ART) model. You may want to use this property to render Coveo ML recommendations in a distinctive fashion in the result list.

Tip
Leading practice

For legacy reasons, several of the preceding properties are duplicated in PascalCase. For example, each item in the results array has both the clickUri and ClickUri properties. You should always use the camelCase version (for example, clickUri).

Example of rendering query results

Executing a search query:

POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1

Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************

Payload (excerpt)

{
  ...
  "excerptlength": 200,
  "q": "karamazov",
  "retrieveFirstSentences": true,
  ...
}

200 OK response body (excerpt)

{
  ...
  "results": [
    {
      ...
      "clickUri": "https://example.com/books/the-brothers-karamazov",
      "excerpt": "The Brothers Karamazov is a passionate philosophical novel set in 19th-century Russia ... one of the supreme achievements in world literature.",
      "excerptHighlights": [
        {
          "length": 9,
          "offset": 13
        }
      ],
      "firstSentences": "The Brothers Karamazov is a passionate philosophical novel set in 19th-century Russia, that enters deeply into the ethical debates of God, free will, and morality. It's a spiritual drama of moral ...",
      "firstSentencesHighlights": [
        {
          "length": 9,
          "offset": 13
        }
      ],
      "isRecommendation": true,
      "printableUri": "https://example.com/books/the-brothers-karamazov",
      "printableUriHighlights": [
        {
          "length": 9,
          "offset": 39
        }
      ],
      "raw": {
        ...
        "author": "Fyodor Dostoyevsky",
        "permanentid": "648a63d6a19545297692b4ae41a7d5e947c711be5f3c23dff69af3106960",
        ...
      },
      "summary": null,
      "summaryHighlights": [],
      "title": "The Brothers Karamazov",
      "titleHighlights": [
        {
          "length": 9,
          "offset": 13
        }
      ],
      "uri": "https://example.com/books/the-brothers-karamazov",
      ...
    },
    ...next results...
  ],
  ...
}

Open query results

When the user opens a query result in a result list, such as by clicking a link which targets the corresponding item:

  1. Call the UA Write API to log the corresponding click event. In the request body:

    • Set the actionCause property to:

    • Include the following key-value pairs (if available) in the customData property:

      • "author": <author>

      • "documentTitle": <documentTitle>

      • "documentUrl": <documentUrl>

      • "contentIdKey": <contentIdKey>

      • "contentIdValue": <contentIdValue>

      where:

      • <author> (string) is the raw.author value of the clicked query result item. This can be an empty string.

      • <documentTitle> (string) is the title value of the clicked query result item.

      • <documentUrl> (string) is the uri value of the clicked query result item.

      • <contentIdKey> (string) is the name of a field which uniquely and permanently identifies the clicked item.

        Tip
        Leading practice

        If this is unavailable, such as if the clicked item resides in a Push source that doesn’t populate the permanentid field with metadata, use "urihash".

      • <contentIdValue> (string) is the value of the field whose name was specified in <contentIdKey>.

        Tip
        Leading practice

        Use the raw.permanentid value of the clicked query result item.

        If this is unavailable, use the raw.urihash value of the clicked query result item.

    • Set other required or optional properties as needed, such as language, originLevel1, or originLevel2.

  2. When the UA Write API returns, redirect the client as appropriate, using the clickableUri value of the clicked query result item.

Examples of opening query results

  1. Logging a documentOpen click event:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/click?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "anonymous": false,
      "actionCause": "documentOpen",
      "customData":{
        "contentIdKey": "permanentid",
        "contentIdValue": "648a63d6a19545297692b4ae41a7d5e947c711be5f3c23dff69af3106960",
        "author": "Fyodor Dostoyevsky",
        "documentTitle": "The Brothers Karamazov",
        "documentURL": "https://example.com/books/the-brothers-karamazov"
      },
      "documentPosition": 1,
      "documentTitle": "The Brothers Karamazov",
      "documentUrl": "https://example.com/books/the-brothers-karamazov",
      "language": "en",
      "originLevel1": "BookstoreSearch",
      "originLevel2": "All",
      "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce",
      "sourceName": "example.com",
      ...
    }
  2. Logging a recommendationOpen click event:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/click?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
     ...
      "anonymous": false,
      "actionCause": "recommendationOpen",
      "customData":{
        "contentIdKey": "permanentid",
        "contentIdValue": "8asd8f7a9sfd8asfdasf78afsdh8h87h878g37g872gf8g83gf78g2f387g2",
        "author": "Ivan Turgenev",
        "documentTitle": "Fathers and Sons",
        "documentURL": "https://example.com/books/fathers-and-sons"
      },
      "documentPosition": 2,
      "documentTitle": "Fathers and Sons",
      "documentUrl": "https://example.com/books/fathers-and-sons",
      "language": "en",
      "originLevel1": "BookstoreRecommendation",
      "originLevel2": "",
      "searchQueryUid": "b2d60d3f-b2cf-4018-bfd2-8094d24fa8e9",
      "sourceName": "example.com",
      ...
    }

Preview a result

Notes
  • As a reference, you may want to look at the source code of the Quickview component to see how it’s implemented in the Coveo JavaScript Search Framework.

  • Unlike most other Search API requests in this guide, preview requests are made using the GET endpoint rather than POST.

When the user previews a query result item, such as by clicking Preview:

  1. Prepare a GET request to https://<orgId>.org.coveo.com/rest/search/v2/html?uniqueId=<uniqueId&gt;, where <orgId> is the unique identifier of your organization. In the query string, set <uniqueId> to the raw.uniqueId value of the query result item to preview.

    Tip
    Leading practice

    Although only the uniqueId parameter is required when requesting an HTML document from the Search API, you should send all the parameters that were originally included in the search request that returned the item to preview. This allows the Search API to highlight relevant terms in the HTML response.

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. Call the UA Write API to log the corresponding click event. In the request body:

      • Set the actionCause property to documentQuickview.

      • Include the following key-value pairs (if available) in the customData property:

        • "author": <author>

        • "contentIdKey": <contentIdKey>

        • "contentIdValue": <contentIdValue>

        • "documentTitle": <documentTitle>

        • "documentUrl": <documentUrl>

        where:

        • <author> (string) is the raw.author value of the clicked query result item. This can be an empty string.

        • <contentIdKey> (string) is the name of a field which uniquely and permanently identifies the clicked item.

          Tip
          Leading practice

          If this is unavailable, such as if the clicked item resides in a Push source that doesn’t populate the permanentid field with metadata, use "urihash".

        • <contentIdValue> (string) is the value of the field whose name was specified in <contentIdKey>.

          Tip
          Leading practice

          Use the raw.permanentid value of the clicked query result item.

          If this is unavailable, use the raw.urihash value of the clicked query result item.

        • <documentTitle> (string) is the title value of the clicked query result item.

        • <documentUrl> (string) is the uri value of the clicked query result item.

      • Set other required or optional properties as needed, such as language, originLevel1, or originLevel2.

    2. Render the HTML document.

Examples of previewing a result

  1. Requesting a Preview:

    GET https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2/html?uniqueId=The_Brothers_Karamazov_Unique_Id&locale=en-US&q=karamazov&searchHub=BookstoreSearch&tab=All HTTP/1.1
    
    Authorization: Bearer **********-****-****-****-************

    200 OK response (excerpt)

    <meta http-equiv='Content-Type' content='text/html; charset=CP1252'>
    <base target="_blank" href="https://example.com/books/the-brothers-karamazov">
    <html lang="en"><head>
    ...
      <p>The Brothers
        <span id='CoveoHighlight:1.2.1' style='background-color:#B0FFFF'>Karamazov</span>
        is a passionate philosophical novel set in 19-th century Russia, that enters
        ...
      </p>
    ...
    </body></html>
  2. Logging a documentQuickview click event:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/click?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "anonymous": false,
      "actionCause": "documentQuickview",
      "customData":{
        "contentIdKey": "permanentid",
        "contentIdValue": "648a63d6a19545297692b4ae41a7d5e947c711be5f3c23dff69af3106960",
        "author": "Fyodor Dostoyevsky",
        "documentTitle": "The Brothers Karamazov",
        "documentURL": "https://example.com/books/the-brothers-karamazov"
      },
      "documentPosition": 1,
      "documentTitle": "The Brothers Karamazov",
      "documentUrl": "https://example.com/books/the-brothers-karamazov",
      "language": "en",
      "originLevel1": "BookstoreSearch",
      "originLevel2": "All",
      "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce",
      "sourceName": "example.com",
      ...
    }

Page query results

Note

As a reference, you may want to look at the source code of the Pager component to see how it’s implemented in the Coveo JavaScript Search Framework.

By default, the results array of a query response contains the first ten items that match the query, according to the specified sort criteria. However, you may want to allow users to navigate to a specific page of query results or modify the default page size in your result list implementation. Paging query results involves the following search request parameters:

  • firstResult (unsigned integer)

  • numberOfResults (unsigned integer)

The Search API will return numberOfResults (for example, 50) items, starting from the 0-based index position of the specified firstResult (for example, 10).

When the user changes the page number of the result list, such as by clicking a different page number, an arrow, or a button to modify the number of results per page:

  1. Prepare a new query. Ensure that the firstResult and/or numberOfResults search request parameters are set to the desired values.

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. Call the UA Write API to log the corresponding custom event. In the request body:

      • Set the eventType property to getMoreResults.

      • Set the eventValue property to:

        • pagerNumber if the user has selected a specific page.

        • pagerNext if the user has selected the next page.

        • pagerPrevious if the user has selected the previous page.

        • pagerScrolling if the user has scrolled down to the bottom of the result list (for example, in infinite scroll mode) and an additional "page" of query results needs to be loaded.

        • pagerResize if the user has selected a different number of results to display per page.

      • Include one of the following key-value pairs in the customData property, depending on the specified eventValue:

        • "pagerNumber": <pagerNumber> if eventValue is set to pagernext, pagerPrevious, or pagerNumber.

        • "currentResultsPerPage": <currentResultsPerPage> if eventValue is set to pagerResize.

        where:

        • <pagerNumber> (unsigned integer) is the new page number (for example, 2).

        • <currentResultsPerPage> (unsigned integer) is the new number of results per page (for example, 50).

        Note

        No customData is required if eventValue is set to pagerScrolling.

      • Set other required or optional properties as needed, such as language, originLevel1, or originLevel2.

    2. Render the query results.

Examples of paging query results

  1. Executing a search query when the user, who is currently on page 1, which contains 10 results, selects page 3:

    POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "firstResult": 20,
      "locale": "en-US",
      "searchHub": "BookstoreSearch",
      "tab": "All",
      ...
    }

    200 OK response body (excerpt)

    {
      ...
      "results": [
        ...data to render the result list...
      ],
      "totalCount": 36,
      ...
    }
  2. Logging a pagerNumber custom event for the previous action:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/custom?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "anonymous": false,
      "customData": {
        "pagerNumber": "3"
      },
      "eventType": "getMoreResults",
      "eventValue": "pagerNumber",
      "language": "en",
      "originLevel1": "BookstoreSearch",
      "originLevel2": "All",
      ...
    }

Sort query results

Note

As a reference, you may want to look at the source code of the Sort component to see how it’s implemented in the Coveo JavaScript Search Framework.

The Search API sortCriteria query parameter specifies how results are sorted. This parameter has five possible values which you may want to offer as options to your users:

  • relevancy: Use index ranking factors or weights as well as specified query ranking expressions (QREs) and query ranking functions (QRFs) to compute a ranking score for each item, and sort the results in descending order.

  • date ascending/date descending: Use the @date field to sort the results in the specified order. This field typically contains the last modification date of each item in the index.

  • qre: Use only QRE and QRF to compute a ranking score for each item, and sort the results in descending order. This is similar to relevancy, except that index ranking factors and weights aren’t computed.

  • nosort: Don’t sort the results. The index will return the results in an indeterminate order.

  • @<field> ascending/@<field> descending: Use the value of a custom, sortable field to sort the results in the specified order. <field> represents a result item field name.

    Notes
    • When @<field> ascending/@<field> descending is used, the <field> it’s based on must have its sort option set to true (see Available Boolean field options).

    • It’s possible to combine zero or one date criterion with one or more field sort criteria by separating them with commas (for example, date ascending,@views descending,@likes descending).

By default, sortCriteria is set to relevancy, meaning that query result items are sorted by their ranking score values, which are computed by the index. These score values are based on several ranking factors and weights, such as the proximity of query terms to one another or the term frequency-inverse document frequency. They can also be influenced by other means such as QRE and QRF, Coveo ML ART and CR models, and certain types of query pipeline statements.

When the user chooses a different sortCriteria or sort order for the query results, such as by selecting a value in a Sort By widget:

  1. Prepare a new query. Ensure that the sortCriteria search request parameter is set to the desired value.

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. Call the UA Write API to log the corresponding search event. In the request body:

      • Set the actionCause property to resultsSort.

      • Include the following key-value pair in the customData property:

        • "resultsSortBy": <resultsSortBy>

        where:

        • <resultsSortBy> (string) is the new sortCriteria or sort order, in lowercase and without spaces. For example, dateascending,@sizeascending instead of date ascending,@size ascending.

      • Set other required or optional properties as needed, such as language, originLevel1, or originLevel2.

    2. Render the query results.

Example of sorting query results

  1. Executing a search query when the user selects Date Descending:

    POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "locale": "en-US",
      "q": "tolstoy",
      "searchHub": "BookstoreSearch",
      "sortCriteria": "Date Descending",
      "tab": "All",
      ...
    }

    200 OK response body (excerpt)

    {
      ...
      "duration": 105,
      "searchUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce",
      "results": [
        {
          ...
          "title":"The 19th Century",
          "raw":
            {
              ...
              "date":1375187019000,
              ...
            },
          ...
        },
        {
          ...
          "title":"War and Peace",
          "raw":
            {
              ...
              "date":1375189132000,
              ...
            },
          ...
        },
        {
          ...
          "title":"Russian literature for Dummies",
          "raw":
            {
              ...
              "date":1384880103000,
              ...
            },
          ...
        },
        ...
      ],
      "totalCount": 403,
      ...
    }
  2. Logging a resultsSort search event for the previous action:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/search HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "actionCause": "resultsSort",
      "anonymous": false,
      "customData": {
        "resultsSortBy": "dateascending"
      },
      "language": "en",
      "originLevel1": "BookstoreSearch",
      "originLevel2": "All",
      "queryText": "tolstoy",
      "responseTime": 105,
      "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce",
      ...
    }

Switch result list layouts

Note

As a reference, you may want to look at the source code of the ResultLayoutSelector component to see how it’s implemented in the Coveo JavaScript Search Framework.

When the user chooses a different result list layout, such as by making a selection in a Layout widget:

  1. Call the UA Write API to log the corresponding custom event. In the request body:

    • Set the eventType property to resultsLayout.

    • Set the eventValue property to changeResultsLayout.

    • Include the following key-value pair in the customData property:

      • "resultsLayoutChangeTo": <resultsLayoutChangeTo>

      where:

      • <resultsLayoutChangeTo> (string) is the identifier of the newly selected result list layout. The Coveo JavaScript Search Framework uses the list, card, and table values.

  2. Render the result list with the new layout.

Note

In the Coveo JavaScript Search Framework, query results are rendered using a different set of result templates for each result list layout (list, card, and table).

Example of switching result list layouts

Logging a changeResultsLayout custom event when the user selects the list display:

POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/custom?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1

Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************

Payload (excerpt)

{
  ...
  "anonymous": false,
  "customData": {
    "resultsLayoutChangeTo": "list"
  },
  "eventType": "resultsLayout",
  "eventValue": "changeResultsLayout",
  "language": "en",
  "originLevel1": "BookstoreSearch",
  "originLevel2": "All",
  ...
}

Handle folded results

Note

As a reference, you may want to look at the source code of the Folding component to see how it’s implemented in the Coveo JavaScript Search Framework.

A search interface sometimes supports the folding of related query result items. There are two possible folding actions, the first of which groups items together. The second action, which builds upon the first, orders the grouped items in logical parent-child relationships.

Implementing the first action requires setting the filterField Search API parameter to @<filterField>, where <filterField> is the name of the field to use for grouping. Upon receiving this request, the Search API sends back a list of result items, where each item contains a childResults array of results which have the same <filterField> value. The childResults arrays are sorted using the sortCriteria, and their maximum length is filterFieldRange (the default value is 5).

To implement the second action, you must provide additional parentField and childField parameters in your Search API request, where the parentField value must uniquely identify each item and the childField value is the value of the parent parentField. When the Search API sends back a list of result items, the items in the childResults arrays will also have a parentResult field, which can be used to resolve parent-child relationships within each folded query result.

Notes
  • The Search API doesn’t necessarily return the result list in the logical parent-child ordering. You’ll likely need to write client-side logic to resolve the parent-child relationships within each folded query result, using one or both of the preceding properties.

  • Result folding and duplicate filtering are mutually exclusive.

When a new query is made in a search interface that supports folding:

  1. Prepare a new query. Ensure that filterField, and potentially parentField, childField, and filterFieldRange, are set to the desired values.

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. Call the UA Write API to log the corresponding search event.

    2. Render the folded result list. In addition to the standard properties to use when rendering query result items, the search interface needs to use the childResults field to display items which belong to the same group and, if necessary, the parentResult field to resolve parent-child relationships.

Examples of handling folded results

  1. A bookstore search interface implements the first folding action to group books by series. indexed items contain a bookseriesid field that identifies the series to which each item belongs.

    When the user queries "solzhenitsyn", the search interface sends the following request to the Search API:

    POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "locale": "en-US",
      "q": "solzhenitsyn",
      "filterField":"@bookseriesid",
      "searchHub": "BookstoreSearch",
      "tab": "All",
      ...
    }

    200 OK response body (excerpt)

    {
    ...
      "results": [
        {
          ...
          "title": "The Gulag Archipelago, Vol. 2",
          "raw":
            {
              ...
              "bookseriesid":"GulagArchipelagoHarperClassics",
              ...
            },
          ...
          "childResults": [
            {
              "title": "The Gulag Archipelago, Vol. 1",
              "raw":
                {
                  ...
                  "bookseriesid":"GulagArchipelagoHarperClassics",
                  ...
                },
              ...
            },
            {
              "title": "The Gulag Archipelago, Vol. 3",
              "raw":
                {
                  ...
                  "bookseriesid":"GulagArchipelagoHarperClassics",
                  ...
                },
              ...
            },
          ],
          ...
        },
        {
          ...
          "title": "One Day in the Life of Ivan Denisovich",
          "raw":
            {
              ...
              "bookseriesid":"OneDayLifeIvanDenisovichSignetClassics",
              ...
            },
          ...
          "childResults": [],
          ...
        },
        ...
      ],
      ...
    }

    As you can see in the preceding query response, the Search API returns a list of items grouped by bookseriesid. The results are sorted by relevance (this applies to both the results and childResults arrays). Also, when a book series only contains one item, its childResults array is empty.

  2. A bookstore search interface implements both folding actions to group books by series as well as order them in logical parent-child relationships. indexed items contain a bookseriesid field that identifies the series to which each item belongs. They also contain a bookid field that uniquely identifies each book within its series, if applicable, and a parentbookid that indicates the bookid of the parent book, if applicable.

    When the user queries "solzhenitsyn", the search interface sends the following request to the Search API:

    POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "locale": "en-US",
      "q": "solzhenitsyn",
      "filterField":"@bookseriesid",
      "parentField":"@bookid",
      "childField":"@parentbookid",
      "searchHub": "BookstoreSearch",
      "sortCriteria": "Date Descending",
      "tab": "All",
      ...
    }

    200 OK response body (excerpt)

    {
    ...
      "results": [
        {
          ...
          "title": "The Gulag Archipelago, Vol. 2",
          "raw":
            {
              ...
              "bookseriesid":"GulagArchipelagoHarperClassics",
              "bookid":"GulagArchipelagoHarperClassics2",
              "parentbookid":"GulagArchipelagoHarperClassics1",
              ...
            },
          ...
          "childResults": [
            {
              "title": "The Gulag Archipelago, Vol. 1",
              "raw":
                {
                  ...
                  "bookseriesid":"GulagArchipelagoHarperClassics",
                  "bookid":"GulagArchipelagoHarperClassics1",
                  "parentbookid":"GulagArchipelagoHarperClassics1",
                  ...
                },
              ...
            },
            {
              "title": "The Gulag Archipelago, Vol. 3",
              "raw":
                {
                  ...
                  "bookseriesid":"GulagArchipelagoHarperClassics",
                  "bookid":"GulagArchipelagoHarperClassics3",
                  "parentbookid":"GulagArchipelagoHarperClassics1",
                  ...
                },
              ...
            },
          ],
          ...
        },
        {
          ...
          "title": "One Day in the Life of Ivan Denisovich",
          "raw":
            {
              ...
              "bookseriesid":"OneDayLifeIvanDenisovichSignetClassics",
              ...
            },
          ...
          "childResults": [],
          ...
        },
        ...
      ],
      ...
    }

    As you can see in the preceding query response, the Search API returns a list of items grouped by bookseriesid. The results are sorted by relevance (this applies to both the results and childResults arrays), and the bookid and parentbookid fields are required to resolve the logical ordering. Also, when a book series only contains one item, its childResults array is empty and its parentField and childField fields don’t need to be populated.

Export results

Note

As a reference, you may want to look at the source code of the ExportToExcel component to see how it’s implemented in the Coveo JavaScript Search Framework.

A search interface sometimes offers the possibility to export the result list in Excel or OpenSearch format.

When the user chooses to export the result list, such as by clicking Export to Excel:

  1. Prepare a new query. Ensure that the format property is set to:

    • opensearch-atom or opensearch-rss if the user selected an OpenSearch format.

    • xlsx if the user selected the Excel format.

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. If format is set to xlsx, call the UA Write API to log the corresponding custom event. In the request body:

      • Set the eventType property to misc.

      • Set the eventValue property to exportToExcel.

      Note

      The Coveo JavaScript Search Framework doesn’t currently support exporting in XML format. As a result, if the user chooses to export to XML, there are currently no precise guidelines to follow when logging the corresponding UA event.

    2. Generate a download link for the user.

Examples of exporting results

  1. Executing a search query when the user clicks Export to Excel:

    POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
    
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "format": "xlsx",
      ...
    }
  2. Logging an exportToExcel custom event for the previous action:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/custom?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "anonymous": false,
      "eventType": "misc",
      "eventValue": "exportToExcel",
      "language": "en",
      "originLevel1": "BookstoreSearch",
      "originLevel2": "All",
      ...
    }

Toggle a facet value from a result list item

In some result lists, query result items contain clickable fields which the user can toggle to filter the entire result list (that is, to select or deselect a facet value).

When the user clicks a result list item field, such as the salesforce field:

  1. Prepare a new query. This is the same as the query that’s sent when selecting or deselecting the associated facet value (see Toggle facet values).

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. Call the UA Write API to log the corresponding search event. In the request body:

      • Set the actionCause property to documentField.

      • Include the following key-value pairs in the customData property:

        • "facetField": <facetField>

        • "facetId": <facetId>

        • "facetValue": <facetValue>

        where:

        • <facetField> (string) is the @-prefixed name of the field the toggled facet is based on (for example, @tags).

        • <facetId> (string) is the unique identifier of the toggled facet. Typically, this is the name of the field that this facet is based on (for example, @tags).

        • <facetValue> (string) is the value of the field selected by the user (for example, salesforce).

      • Set other required or optional properties as needed, such as language, originLevel1, or originLevel2.

    2. Update the facet instance.

    3. Render the query results.

Examples of toggling a facet value from a result list item

  1. Executing a search query when the user selects the salesforce item field:

    POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "aq": "(@tags==("salesforce"))",
      "locale": "en-US",
      "q": "coveo",
      "searchHub": "ExternalSearch",
      "tab": "All",
      ...
    }

    200 OK response body (excerpt)

    {
      ...
      "duration": 247,
      "searchUid": "de6cb58a-2abb-4718-a874-cc2162691cd9",
      "results": [
        ...data to render the result list...
      ],
      "totalCount": 272,
      ...
    }
  2. Logging a documentField search event for the previous action:

    POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/search HTTP/1.1
    
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer **********-****-****-****-************

    Payload (excerpt)

    {
      ...
      "actionCause": "documentField",
      "anonymous": false,
      "customData": {
        "facetField": "@tags",
        "facetId": "@tags",
        "facetValue": "salesforce"
      },
      "language": "en",
      "originLevel1": "ExternalSearch",
      "originLevel2": "All",
      "queryText": "coveo",
      "responseTime": 247,
      "searchQueryUid": "de6cb58a-2abb-4718-a874-cc2162691cd9",
      ...
    }