Implement facets using groupBy operations
Implement facets using groupBy operations
This is for:
DeveloperA search interface often includes facets that allow the user to narrow down a query to a specific subset of result items by selecting one or more dynamic filter values. This article provides guidelines for implementing facets on your own, assuming that you can’t use the Coveo JavaScript Search Framework or the Atomic or Headless libraries in your custom search integration with the Coveo Platform.
Notes
|
Standard facet actions
The following table lists some actions that you may want to make available in a facet 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.
Each entry also includes a link to the corresponding implementation guidelines.
Facet action | UA event | actionCause |
eventType |
eventValue |
customData |
Implementation guidelines |
---|---|---|---|---|---|---|
Select a value |
Search |
|
N/A |
N/A |
|
|
Un-select a value |
Search |
|
N/A |
N/A |
|
|
Exclude a value |
Search |
|
N/A |
N/A |
|
|
Un-exclude a value |
Search |
|
N/A |
N/A |
|
|
Reset selected or excluded values |
Search |
|
N/A |
N/A |
|
|
Request more values |
N/A |
N/A |
N/A |
N/A |
N/A |
|
Sort values |
Custom |
N/A |
|
|
|
|
Search for a value |
Custom |
N/A |
|
|
|
Note
It’s important to use the proper
|
Request and render facets
Conceptually, a facet relies on an existing field (for example, @bookauthor
) to render a sorted list of facet values (for example, Poe, Edgar Allan
, Clarke, Arthur C.
, Gibbon, Edward
), each of which is accompanied by an estimated number of occurrences in the current query result set.
You can request the necessary data to render one or more facets through the groupBy
search request parameter.
Each Group By operation that you include in a query populates a distinct object in the groupByResults
array of that query response body.
Most of the time, when a query is sent from a faceted search interface, you’ll want to request and render or update facets. To do so:
-
In the query, populate the
groupBy
search request parameter with a distinct Group By operation for each facet to render.NoteOnly the
field
Group By parameter is required. By default, when a Group By operation merely contains thefield
parameter, this operation requests up to ten facet values sorted by descendingscore
order, or alphabetically in the case of ranged facets. You can use themaximumNumberOfValues
andsortCriteria
Group By parameters to override these settings (see Request additional facet values and Sort facet values).If the specified
field
references a field that doesn’t exist in the index, or whosefacet
option is set tofalse
, the correspondinggroupByResults
object in the query response body will contain an emptyvalues
array.Likewise, the
values
array will be empty if no value matching the query is found for the referenced field.In any case, a
groupByResults
object with an emptyvalues
array typically means that the corresponding facet shouldn’t be rendered in the search interface. -
When the query is executed and the Search API returns, for each facet to render in the search interface:
-
In the query response body, retrieve the
groupByResults
object whosefield
value matches the field on which the facet relies.Notes-
In a
groupByResults
object, thefield
andglobalComputedFieldResults
properties, as well as allvalues
object properties, such aslookupValue
andnumberOfResults
, are duplicated in PascalCase for legacy reasons. For example, each item in thevalues
array of agroupByResults
item has both thenumberOfResults
andNumberOfResults
properties.We recommend that you always use the camelCase version (for example,
numberOfResults
), and the examples in this article only include camelCase properties. -
A Group By operation merely retrieves an array of
groupByResults
at query time. It has no effect whatsoever on theresults
array of the query response body, which contains the actual query result items. If you want to group query result items based on the value of a specific field, populate thefilterField
search request parameter as necessary before executing the query (see Handle folded results).
-
-
Use the
lookupvalue
(orvalue
) andnumberOfResults
attributes of each object in thevalues
array of thegroupByResults
object retrieved in step 2.a to render or update the facet.NoteFor a given object in the
values
array, thelookupValue
andvalue
attributes will contain the same data, unless the object is a range value.
-
Example of requesting and rendering facets
Executing a query which includes Group By operations to retrieve three facets (Book Author, Book Genre, and Book Format):
POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{
...
"groupBy": [
...
{
"field": "@bookauthor",
"maximumNumberOfValues": 3
},
{
"field": "@bookgenre"
}
{
"field": "@bookformat"
},
...
],
"q": "fall",
...
}
200 OK response body (excerpt)
{
...
"groupByResults": [
...
{
"field": "bookauthor",
"globalComputedFieldResults": [],
"values": [
{
"computedFieldResults": [],
"lookupValue": "Poe, Edgar Allan",
"numberOfResults": 6,
"score": 631739,
"value": "Poe, Edgar Allan",
"valueType": "Standard"
}
{
"computedFieldResults": [],
"lookupValue": "Clarke, Arthur C.",
"numberOfResults": 11,
"score": 399555,
"value": "Clarke, Arthur C.",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Gibbon, Edward",
"numberOfResults": 29,
"score": 380154,
"value": "Gibbon, Edward",
"valueType": "Standard"
}
]
},
{
"globalComputedFieldResults": [],
"field": "bookgenre",
"values": [
{
"computedFieldResults": [],
"lookupValue": "Fantasy",
"numberOfResults": 78,
"score": 48927523,
"value": "Fantasy",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Mystery",
"numberOfResults": 89,
"score": 8610185,
"value": "Mystery",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Science-Fiction",
"numberOfResult": 22,
"score": 7478698,
"value": "Science-Fiction",
"valueType": "Standard"
},
...
]
},
{
"globalComputedFieldResults": [],
"field": "bookformat",
"values": [
{
"computedFieldResults": [],
"score": 1752838,
"value": "Paperback",
"numberOfResults": 322,
"valueType": "Standard"
},
{
"computedFieldResults": [],
"score": 820350,
"value": "Ebook",
"numberOfResults": 261,
"valueType": "Standard"
},
{
"computedFieldResults": [],
"score": 70372,
"value": "Hardcover",
"numberOfResults": 178,
"valueType": "Standard"
}
]
},
...
],
...
}
Request ranged facets
Note
As a reference, you may want to look at the source code of the |
When a facet is based on a numeric or date field, its values must refer to ranges.
The easiest way to request ranged facet values is to set the generateAutomaticRanges
Group By parameter to true
when requesting the ranged facet.
This will cause the index to automatically compute ranges based on the minimum and maximum values of the field referenced by the Group By operation.
This simple approach doesn’t work with facets based on dynamic fields created by Query functions.
It also doesn’t allow retrieved ranged facet values to have custom strings as their lookupValue
.
One work-around is to request an explicit set of ranges using the rangeValues
Group By parameter.
Each object in the rangeValues
array must have a start
(for example, 0
) and an end
(for example, 100
).
Optionally, it may also have a label
(for example, Short
), which will be used as a custom lookupValue
.
By default, the end
value isn’t included in the requested range, but you can set endInclusive
to true
to modify this behavior.
Note
By default, ranged facet values are sorted alphabetically based on their Example
In the One way to work around this issue when using the |
Example of requesting ranged facets
Executing a query which includes Group By operations to retrieve two ranged facets (Book Price and Book Length):
POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{
...
"groupBy": [
...
{
"field": "@bookprice",
"generateAutomaticRanges": true
},
{
"field": "@booklength",
"rangeValues": [
{
"start": 0,
"end": 100,
"label": "Short"
},
{
"start": 100,
"end": 500,
"label": "Medium"
},
{
"start": 500,
"end": 10000,
"label": "Long"
}
],
"sortCriteria": "nosort"
},
...
],
"q": "fall",
...
}
200 OK response body (excerpt)
{
...
"groupByResults": [
...
{
"globalComputedFieldResults": [],
"field": "bookprice",
"values": [
{
"computedFieldResults": [],
"lookupValue": "100..110",
"numberOfResults": 20,
"score": 0,
"value": "100.000000..110.000000",
"valueType": "Standard"
}
{
"computedFieldResults": [],
"lookupValue": "10..20",
"numberOfResults": 424,
"score": 0,
"value": "10.000000..20.000000",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "20..30",
"numberOfResults": 217,
"score": 0,
"value": "20.000000..30.000000",
"valueType": "Standard"
},
...
]
},
{
"globalComputedFieldResults": [],
"field": "booklength",
"values": [
{
"computedFieldResults": [],
"lookupValue": "Short",
"numberOfResults": 138,
"score": 161,
"value": "0..99",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Medium",
"numberOfResults": 970,
"score": 432,
"value": "100..499",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Long",
"numberOfResults": 553,
"score": 168,
"value": "500..9999",
"valueType": "Standard"
}
]
},
...
],
...
}
Request slider facets
Note
As a reference, you may want to look at the source code of the |
You may want to allow users to specify their own custom range of values through a slider facet rather than selecting or excluding predefined values from a ranged facet.
One way to request the necessary data to render a slider facet is to perform a Group By operation in which maximumNumberOfValues
is set to 1
, generateAutomaticRanges
is set to true
, and advancedQueryOverride
is set to an all-inclusive query syntax expression (for example, @uri
).
This forces the index to compute a single range value starting with the lowest and ending with the highest value of the field referenced by the Group By operation.
When the user interacts with the slider facet to specify a custom range, you can then alter the current advanced query expression (aq
) accordingly (see Toggle facet values).
Example of requesting slider facets
Executing a query which includes a Group By operation to retrieve the Book Price slider facet:
POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{
...
"groupBy": [
...
{
"field": "@bookprice",
"generateAutomaticRanges": true,
"maximumNumberOfValues": 1,
"advancedQueryOverride": "@uri"
},
...
],
"q": "fall",
...
}
200 OK response body (excerpt)
{
...
"groupByResults": [
...
{
"globalComputedFieldResults": [],
"field": "bookprice",
"values": [
{
"computedFieldResults": [],
"lookupValue": "5..110",
"numberOfResults": 1891,
"score": 0,
"value": "5.000000..110.000000",
"valueType": "Standard"
}
]
},
...
],
...
}
Toggle facet values
In a typical faceted search interface, the user can toggle (that is, select and un-select or exclude and un-exclude) any number of facet values to alter the current advanced query expression (aq
).
When the user interacts with a facet in such a way:
-
Generate a query syntax expression that represents the updated facet state.
In a disjunctive facet based on the @bookauthor
field, the currently selected values are Poe, Edgar Allan
and Clarke, Arthur C.
The user interacts with the facet to exclude the Gibbon, Edward
value.
The updated { } state could be represented by a query syntax expression such as (@bookauthor==("Poe, Edgar Allan", "Clarke, Arthur C.")) (NOT @author==("Gibbon, Edward"))
.
-
Prepare a new query. Ensure that the
aq
search request parameter includes the expression generated in step 1. -
Call the Search API to execute the query prepared in step 2. When the Search API returns:
-
Call the UA Write API to log the corresponding search event. In the request body:
-
Set the
actionCause
property to:-
facetSelect
if the user has selected a single facet value. -
facetUnselect
if the user has un-selected a single facet value. -
facetExclude
if the user has excluded a single facet value. -
facetUnexclude
if the user has un-excluded a single facet value. -
facetClearAll
if the user has cleared all previously selected or excluded values. -
facetRangeSlider
orfacetRangeGraph
(whichever is more appropriate) if the user has selected a custom range of numeric or date values through a slider facet.
-
-
Include the following key-value pairs in the
customData
property:-
"facetField": <facetField>
-
"facetId": <facetId>
-
"facetTitle": <facetTitle>
(don’t include ifactionCause
isfacetRangeSlider
orfacetRangeGraph
) -
"facetValue": <facetValue>
(don’t include ifactionCause
isfacetClearAll
,facetRangeSlider
, orfacetRangeGraph
) -
"facetRangeStart": <facetRangeStart>
(only include ifactionCause
isfacetRangeSlider
orfacetRangeGraph
) -
"facetRangeEnd": <facetRangeEnd>
(only include ifactionCause
isfacetRangeSlider
orfacetRangeGraph
)
where:
-
<facetField>
(string) is the@
-prefixed name of the field this facet is based on (for example,@booklength
). -
<facetId>
(string) is the unique identifier of the facet in which one or more values were toggled. Typically, this is the name of the field this facet is based on (for example,@booklength
). -
<facetTitle>
(string) is the display name of the facet in which one or more values were toggled. Typically, this is the human-readable name of the field this facet is based on (for example,Book Length
). -
<facetValue>
(string) is the name of the toggled facet value (for example,Short
). -
<facetRangeStart>
(string) is the first value of the user-specified range. -
<facetRangeEnd>
(string) is the last value of the user-specified range.
NoteYou have to use the appropriate
actionCause
andcustomData
values if you’re interacting with a facet indirectly in your own custom component. -
-
Set other required or optional properties as needed, such as
language
,originLevel1
, ororiginLevel2
.
-
-
Update all of the facets in the search interface.
-
Interact with a facet indirectly
The Coveo JavaScript Search Framework includes components that allow users to interact with facets indirectly, such as the Breadcrumb
and FieldValue
components.
If you implement your own components, be sure to use the appropriate actionCause
and customData
values when logging a search event after the user has indirectly toggled one or more facet values:
Action | actionCause |
customData |
---|---|---|
Select or un-select a single facet value by interacting with a query result |
|
|
Un-select or un-exclude a single facet value by interacting with breadcrumbs |
|
|
Clear all selected or excluded facet values by interacting with breadcrumbs |
|
N/A |
Examples of toggling facet values
-
Executing a query after the user has excluded the
Medium
value from the Book Length facet by interacting with the facet directly:POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1 Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{ ... "aq": "(NOT @booklength==(100..499))", "locale": "en-US", "groupBy": [ ... ], "q": "fall", "searchHub": "BookstoreSearch", "tab": "All", ... }
200 OK response body (excerpt)
{ ... "duration": 86, "groupByResults": [ ... ], "results": [ ... ], "searchUid": "a1d15d1b-5802-47ac-959f-35a0f2ca72de", ... }
-
Executing a query after the user has selected the
Hardcover
value from the Book Format facet by interacting with a query result:POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1 Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{ ... "aq": "(NOT @booklength==(100..499)) (@bookformat==(\"Hardcover\"))", "locale": "en-US", "groupBy": [ ... ], "q": "fall", "searchHub": "BookstoreSearch", "tab": "All", ... }
200 OK response body (excerpt)
{ ... "duration": 75, "groupByResults": [ ... ], "results": [ ... ], "searchUid": "38e17ca1-c362-44a0-90bf-09669d908af3", ... }
-
Executing a query after the user has un-excluded the
Medium
value from the Book Length facet by interacting with the breadcrumbs:POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1 Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{ ... "aq": "(@bookformat==(\"Hardcover\"))", "locale": "en-US", "groupBy": [ ... ], "q": "fall", "searchHub": "BookstoreSearch", "tab": "All", ... }
200 OK response body (excerpt)
{ ... "duration": 67, "groupByResults": [ ... ], "results": [ ... ], "searchUid": "7b83db54-ce56-4837-8c76-9f63b39b54a6", ... }
-
Logging a batch of search events for the three previous actions:
POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/searches?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
[ { ... "actionCause": "facetExclude", "advancedQuery": "(NOT @booklength==(100..499))", "customData": { ... "facetField": "@booklength", "facetId": "@booklength", "facetTitle": "Book Length", "facetValue": "Medium", ... }, "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", "queryText": "fall", "responseTime": 86, "searchQueryUid": "a1d15d1b-5802-47ac-959f-35a0f2ca72de", ... }, { ... "actionCause": "documentField", "advancedQuery": "(NOT @booklength==(100..499)) (@bookformat==(\"Hardcover\"))", "customData": { ... "facetField": "@bookformat", "facetId": "@bookformat", "facetTitle": "Book Format", "facetValue": "Hardcover", ... }, "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", "queryText": "fall", "responseTime": 75, "searchQueryUid": "38e17ca1-c362-44a0-90bf-09669d908af3", ... }, { ... "actionCause": "breadcrumbFacet", "advancedQuery": "(@bookformat==(\"Hardcover\"))", "customData": { ... "facetField": "@booklength", "facetId": "@booklength", "facetTitle": "Book Length", "facetValue": "Medium", ... }, "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", "queryText": "fall", "responseTime": 67, "searchQueryUid": "7b83db54-ce56-4837-8c76-9f63b39b54a6", ... } ]
Request additional facet values
The maximumNumberOfValues
Group By parameter allows you to specify up to how many facet values the index may retrieve to populate the values
array of a given groupByResults
object (the default value is 10
).
When completeFacetWithStandardValues
is set to true
and the cardinality of allowedValues
is lower than the maximumNumberOfValues
, the index will try to retrieve standard values until the values
array contains maximumNumberOfValues
.
You may also want to allow the user to autonomously request more values to be displayed in a facet. When the user interacts with a facet in such a way:
-
Prepare a new query. Ensure that the
numberOfResults
search request parameter is set to0
. In thegroupBy
search request parameter, include a Group By operation to update the facet for which the user has requested additional values. In this Group By operation:-
Set
field
to the name of the field that the facet is based on (for example,@bookauthor
). -
In the
allowedValues
array, include all of the values currently displayed by the facet (for example,Poe, Edgar Allan
,Clarke, Arthur C.
,Gibbon, Edward
). -
Set
maximumNumberOfValues
to a higher value than the one that was specified the last time the facet was requested (for example,6
). -
Set
completeFacetWithStandardValues
totrue
. -
Set all other Group By parameters to the value they were the last time the facet was requested.
NoteAlthough this query isn’t meant to return actual result items, you should include the other search request parameters as usual. This way, it will represent the current state of the search interface, aside from
numberOfResults
being forcefully set to0
andgroupBy
not necessarily containing all of the operations required to update facets. Otherwise, the retrievedgroupByResults
object may not contain accurate or consistent facet values or occurrence counts. -
-
Call the Search API to execute the query prepared in step 1. When the Search API returns, re-render the updated facet as appropriate.
Note
When the user requests additional facet values to be displayed:
|
Example of requesting additional facet values
Executing a query after the user has requested additional values to be displayed in the Book Author facet:
POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{
...
"aq": "(@bookformat==(\"Hardcover\"))",
"groupBy": [
{
"allowedValues": [
"Poe, Edgar Allan",
"Clarke, Arthur C.",
"Gibbon, Edward"
],
"completeFacetsWithStandardValues": true,
"field": "@bookauthor",
"maximumNumberOfValues": 6
}
],
"locale": "en-US",
"numberOfResults": 0,
"q": "fall",
"searchHub": "BookstoreSearch",
"tab": "All",
...
}
200 OK response body (excerpt)
{
...
"groupByResults": [
{
"field": "bookauthor",
"globalComputedFieldResults": [],
"values": [
{
"computedFieldResults": [],
"lookupValue": "Poe, Edgar Allan",
"numberOfResults": 1,
"score": 631739,
"value": "Poe, Edgar Allan",
"valueType": "Standard"
}
{
"computedFieldResults": [],
"lookupValue": "Clarke, Arthur C.",
"numberOfResults": 3,
"score": 399555,
"value": "Clarke, Arthur C.",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Gibbon, Edward",
"numberOfResults": 7,
"score": 380154,
"value": "Gibbon, Edward",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Beckett, Samuel",
"numberOfResults": 1,
"score": 271647,
"value": "Beckett, Samuel",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Delany, Samuel R.",
"numberOfResults": 2,
"score": 240684,
"value": "Delany, Samuel R.",
"valueType": "Standard"
},
{
"computedFieldResults": [],
"lookupValue": "Camus, Albert",
"numberOfResults": 1,
"score": 165923,
"value": "Camus, Albert",
"valueType": "Standard"
}
]
}
],
"results": [],
...
}
Sort facet values
The sortCriteria
Group By parameter allows you to specify in what order the index should return the values
of a groupByResults
object (the default value being Score
for regular values, or AlphaAscending
for range values).
You may also want to allow the user to autonomously change facet sort criteria. When the user interacts with a facet in such a way:
-
Prepare a new query. Ensure that the
numberOfResults
search request parameter is set to0
. In thegroupBy
search request parameter, include a Group By operation to update the facet for which the user has selected a new sort criteria. In this Group By operation:-
Set
field
to the name of the field that the facet is based on (for example,@bookformat
). -
Set
sortCriteria
to the value that corresponds to the user’s selection. -
Set all other Group By parameters to the value they were the last time the facet was requested.
NoteAlthough this query isn’t meant to return actual result items, you should include the other search request parameters as usual. This way, it will represent the current state of the search interface, aside from
numberOfResults
being forcefully set to0
andgroupBy
not necessarily containing all of the operations required to update facets. Otherwise, the retrievedgroupByResults
object may not contain accurate or consistent facet values or occurrence counts. -
-
Call the Search API to execute the query prepared in step 1. When the Search API returns:
-
Call the UA Write API to log the corresponding custom event. In the request body:
-
Set the
eventType
property tofacet
. -
Set the
eventValue
property tofacetUpdateSort
. -
Include the following key-value pairs in the
customData
property:-
"criteria": <criteria>
-
"facetField": <facetField>
-
"facetId": <facetId>
-
"facetTitle": <facetTitle>
where:
-
<criteria>
(string) is the new selected sort criteria (for example,AlphaAscending
). -
<facetField>
(string) is the@
-prefixed name of the field this facet is based on (for example,@bookformat
). -
<facetId>
(string) is the unique identifier of the facet in which the sort criteria was changed. Typically, this is the name of the field this facet is based on (for example,@bookformat
). -
<facetTitle>
(string) is the display name of the facet in which the sort criteria was changed. Typically, this is the human-readable name of the field this facet is based on (for example,Book Format
).
-
-
Set other required or optional properties as needed, such as
language
,originLevel1
, ororiginLevel2
.
-
-
Re-render the facet as appropriate.
-
Examples of sorting facet values
-
Executing a query after the user has selected an alphabetical sort criteria for the Book Format facet:
POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1 Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{ ... "groupBy": [ { "field": "@bookformat", "sortCriteria": "AlphaAscending" } ], "locale": "en-US", "numberOfResults": 0, "q": "fall", "searchHub": "BookstoreSearch", "tab": "All", ... }
200 OK response body (excerpt)
{ ... "groupByResults": [ { "globalComputedFieldResults": [], "field": "bookformat", "values": [ { "computedFieldResults": [], "score": 0, "value": "Ebook", "numberOfResults": 261 }, { "computedFieldResults": [], "score": 0, "value": "Hardcover", "numberOfResults": 178 }, { "computedFieldResults": [], "score": 0, "value": "Paperback", "numberOfResults": 322 } ] } ], "results": [], ... }
-
Logging a 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)
{ ... "customData": { ... "criteria": "AlphaAscending", "facetField": "@bookformat", "facetId": "@bookformat", "facetTitle": "Book Format", ... }, "eventType": "facet", "eventValue": "facetUpdateSort", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", ... }
Use custom facet sort criteria
If you want to define a custom facet sort criteria based on an aggregate operation performed on the values of a numeric field (that is, average
, maximum
, minimum
, or sum
), use the computedFields
Group By parameter along with either the ComputedFieldAscending
or ComputedFieldDescending
sortCriteria
value (see Computed fields).
Notes
|
Example of using custom facet sort criteria
Executing a query which includes a Group By operation to sort the Book Author facet values based on average book ratings:
POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{
...
"groupBy": [
...
{
"field": "@bookauthor",
"maximumNumberOfValues": 3,
"computedFields": [
{
"field": "@bookrating",
"operation": "average"
}
],
"sortCriteria": "ComputedFieldDescending"
},
...
],
...
}
200 OK response body (excerpt)
{
...
"groupByResults": [
...
{
"field": "bookauthor",
"globalComputedFieldResults": [ 6.7389380531 ],
"values": [
{
"computedFieldResults": [ 8.9146341463 ],
"lookupValue": "Follett, Ken",
"numberOfResults": 3,
"score": 0,
"value": "Follett, Ken",
"valueType": "Standard"
}
{
"computedFieldResults": [ 8.307142857 ],
"lookupValue": "Simmons, Dan",
"numberOfResults": 3,
"score": 0,
"value": "Simmons, Dan",
"valueType": "Standard"
},
{
"computedFieldResults": [ 8.058823529 ],
"lookupValue": "Golding, William",
"numberOfResults": 2,
"score": 0,
"value": "Golding, William",
"valueType": "Standard"
}
]
},
...
],
...
}
Perform facet search
You may want to allow users to look for specific facet values by typing into a dedicated search input within a facet. When a user interacts with a facet in such a way:
-
On each valid keystroke in the corresponding facet search input:
-
Retrieve the current value from the facet search input (for example,
a
). -
Prepare a new query. Ensure that the
numberOfResults
search request parameter is set to0
. In thegroupBy
search request parameter, include a Group By operation for the facet in which the user is searching. In this Group By operation:-
Set
field
to the name of the field that the searched facet is based on (for example,@bookgenre
). -
In the
allowedValues
array, include the original as well as the-prefixed and
-suffixed values retrieved in step 1.a (for example,
a
and*a*
). -
Set
maximumNumberOfValues
to the maximum number of matching values to retrieve through facet search (for example,4
). The default value is10
. -
Set all other Group By parameters to the value they were the last time the facet was requested.
NoteAlthough this query isn’t meant to return actual result items, you should include the other search request parameters as usual. This way, it will represent the current state of the search interface, aside from
numberOfResults
being forcefully set to0
andgroupBy
not necessarily containing all of the operations required to update facets. Otherwise, the retrievedgroupByResults
object may not contain accurate or consistent facet values or occurrence counts. -
-
Call the Search API to execute the query prepared in step 1.b. When the Search API returns:
-
Call the UA Write API to log the corresponding custom event. In the request body:
-
Set the
eventType
property tofacet
. -
Set the
eventValue
property tofacetSearch
. -
Include the following key-value pairs in the
customData
property:-
"facetField": <facetField>
-
"facetId": <facetId>
-
"facetTitle": <facetTitle>
where:
-
<facetField>
(string) is the@
-prefixed name of the field this facet is based on (for example,@bookgenre
). -
<facetId>
(string) is the unique identifier of the facet in which facet search was performed. Typically, this is the name of the field this facet is based on (for example,@bookgenre
). -
<facetTitle>
(string) is the display name of the facet in which facet search was performed. Typically, this is the human-readable name of the field this facet is based on (for example,Book Genre
).
-
-
Set other required or optional properties as needed, such as language`,
originLevel1
, ororiginLevel2
.
-
-
Render the retrieved facet values as appropriate (for example, in a dedicated result list below the facet search input).
-
-
Note
These guidelines suggest a facet search implementation which is based on that of the Coveo JavaScript Search Framework (that is, wildcard pattern matching as the user types). You may opt to use an entirely different approach for your own implementation (to consume less queries per month (QPM), for example). |
Examples of performing facet search
-
Executing a query after the user has typed
a
in the dedicated search input of the Book Genre facet:POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1 Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************
Payload (excerpt)
{ ... "groupBy": [ { "allowedValues": [ "a", "*a*" ], "field": "@bookgenre", "maximumNumberOfValues": 4 } ], "locale": "en-US", "numberOfResults": 0, "q": "fall", "searchHub": "BookstoreSearch", "tab": "All", ... }
200 OK response body (excerpt)
{ ... "groupByResults": [ { "values": [ { "computedFieldResults": [], "lookupValue": "Fantasy", "numberOfResults": 78, "score": 48927523, "value": "Fantasy", "valueType": "Standard" }, { "computedFieldResults": [], "lookupValue": "Romance", "numberOfResults": 106, "score": 1125782, "value": "Romance", "valueType": "Standard" }, { "computedFieldResults": [], "lookupValue": "Adventure", "numberOfResults": 47, "score": 1063015, "value": "Adventure", "valueType": "Standard" }, { "computedFieldResults": [], "lookupValue": "Biography", "numberOfResults": 94, "score": 831924, "value": "Biography", "valueType": "Standard" } ] } ], "results": [], ... }
-
Logging a 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)
{ ... "customData": { ... "facetField": "@bookgenre", "facetId": "@bookgenre", "facetTitle": "Book Genre", ... }, "eventType": "facet", "eventValue": "facetSearch", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", ... }