Using GraphQL Search API
Find API Documentation
Section titled “Find API Documentation”NOTE: This API and its endpoints are in BETA. Beta Services as described by Section 2.e. of the terms of services located here
Overview
Section titled “Overview”The Find API allows you to search for documents in an index based on specific parameters.
Basic Usage
Section titled “Basic Usage”To search for documents using the find
query. Below, you can see examples:
Find query basic example
Section titled “Find query basic example”query FindSimpleQuery { find(query: "hello") { total documents { id score data } }}
Find query advance example
Section titled “Find query advance example”query FindAdvanceQuery { find( query: "Austin" filter: "post_type:post,page" fields: [{ name: "title", weight: 2 }, { name: "description" }] orderBy: [{ field: "published_at", direction: desc }] limit: 100 offset: 200 tolerance: { name: fuzzy, fuzzyDistance: 2 } ) { total documents { id score data } }}
You can write the same query with separated variables:
query FindAdvanceQuery( $query: String! $filter: String $fields: [SearchField!] $orderBy: [OrderBy!] $limit: Int! $offset: Int! $tolerance: SearchOption!) { find( query: $query filter: $filter fields: $fields orderBy: $orderBy limit: $limit offset: $offset tolerance: $tolerance ) { total documents { id score data } }}
GraphQL Variables
{ "query": "Austin", "filter": "post_type:post,page", "orderBy": [ { "field": "published_at", "direction": "desc" } ], "offset": 200, "limit": 100, "fields": [{ "name": "title", "weight": 2 }, { "name": "description" }], "tolerance": { "name": "fuzzy", "fuzzyDistance": 2 }}
The query returns a SearchResult
object that includes fields:
total
- an integer of the total documents matching the query. Independent to offset and limit arguments.documents
- an array of search documents with fields:id
is unique id of the document in the indexscore
is a relevance score, which determines how closely each document matches the query
Advanced Usage
Section titled “Advanced Usage”Logical operators: AND, OR, NOT
Section titled “Logical operators: AND, OR, NOT”Using NOT
search operator:
query FindNotQuery { find(query: "Austin NOT Minnesota") { total documents { id score data } }}
Using AND
search operator:
query FindAndQuery { find(query: "New York AND Texas") { total documents { id score data } }}
Using OR
search operator:
query FindOrQuery { find(query: "New York OR Texas") { total documents { id score data } }}
Search field value with greater, less or equal operator
Section titled “Search field value with greater, less or equal operator”query FindRangeQuery { find(query: "seats.count:(>4 AND <20)") { total documents { id score data } }}
The seats.count
field has a value greater than 4 and lower than 20.
Filtering for exact keywords
Section titled “Filtering for exact keywords”It is possible to have two categories which might share the same keywords, Car
and Car Sales
.
query FindFilterQuery { find(query: "Toyota", filter: "categories.name:Car") { total documents { id score data } }}
Executing the query above will return records where the categories.name
field contains both Car
and Car Sales
etc.
If we only want to return records with Car
we must use the keyword
field i.e if the path to the field is categories.name
we can update it to be categories.name.keyword
query FindKeywordFilterQuery { find(query: "Toyota", filter: "categories.name.keyword:Car") { total documents { id score data } }}
Executing the query above will ensure only the categories which match Car
will be returned.
Ordering
Section titled “Ordering”The orderBy
input is an array of objects that specify how the results of the find query should be sorted. Each object in the orderBy
array has two properties: field
and direction
.
Ordering by dates
Section titled “Ordering by dates”The following query sorts documents in descending order using the post_date_gmt
field:
query OrderByQueryWithDates { find( query: "my search query" orderBy: [{field: "post_date_gmt", direction: desc}] ) { total documents { id sort } }}
Ordering by strings
Section titled “Ordering by strings”NOTE: String fields can only be used in orderBy
by appending a subfield which is automatically present for all string fields, this field is called keyword
.
The following query sorts documents in ascending order using a string field post_title
, we must then append .keyword
to enable string sorting.
query OrderByQueryWithStrings { find( query: "my search query" orderBy: [{field: "post_title.keyword", direction: asc}] ) { total documents { id sort } }}
Ordering by numbers
Section titled “Ordering by numbers”The following query sorts documents in ascending order using the price
field:
query OrderByQueryWithNumbers { find( query: "my search query" orderBy: [{field: "price", direction: asc}] ) { total documents { id sort } }}
Ordering by multiple clauses
Section titled “Ordering by multiple clauses”It is possible to order by one or more clauses, each subsequent ordering clause
has less priority than the preceding clause. For example if we order by price
and then post_date_gmt
, the post_date_gmt
comes into effect when two or more records with the same price
are the same.
The following query sorts documents using multiple fields, price
and post_date_gmt
:
query OrderByQueryWithMultipleClauses { find( query: "my search query" orderBy: [ {field: "price", direction: asc}, {field: "post_date_gmt", direction: asc}, ] ) { total documents { id sort } }}
Cursor pagination
Section titled “Cursor pagination”Search also supports cursor pagination.
Notes:
orderBy
would need to be provided in order to avoidsort
field of returned documents being empty- In order cursor pagination to work properly,
{field:"_score"}
can’t be provided alone, since it’s a calculated field and needs a second standard field to work as “tiebreaker”.
Here is an example:
query FindTest { find( query: "test" orderBy: [{field:"_score"},{field: "post_date_gmt", direction: desc}] ) { total documents { id sort } }}
And result documents returned are:
{ "data": { "find": { "total": 5, "documents": [ { "id": "post:19", "sort": [ "4.680951", "2024-01-23T11:06:37" ] }, { "id": "post:17", "sort": [ "4.680951", "2024-01-23T11:06:25" ] }, { "id": "post:15", "sort": [ "4.680951", "2024-01-23T11:06:14" ] }, { "id": "post:13", "sort": [ "4.680951", "2024-01-23T11:06:01" ] }, { "id": "post:10", "sort": [ "4.680951", "2024-01-23T11:05:46" ] } ] } }}
For returning the results after post:17
we need to provide the sort
of that document and make the following call:
query FindTest { find( query: "test" orderBy: [{field:"_score"},{field: "post_date_gmt", direction: desc}] searchAfter:["4.680951", "2024-01-23T11:06:25"] ) { total documents { id sort } }}
which will return:
{ "data": { "find": { "total": 5, "documents": [ { "id": "post:15", "sort": [ "4.680951", "2024-01-23T11:06:14" ] }, { "id": "post:13", "sort": [ "4.680951", "2024-01-23T11:06:01" ] }, { "id": "post:10", "sort": [ "4.680951", "2024-01-23T11:05:46" ] } ] } }}
Semantic / Hybrid Search
Section titled “Semantic / Hybrid Search”Semantic search uses machine learning to interpret the meaning of words and phrases. The results of a semantic search will return documents matching the meaning of a query, as opposed to full text search that literally matches words in the query.
Hybrid search is a combination of full-text search and semantic search to deliver more relevant and comprehensive results.
Before using Semantic / Hybrid search, you need to configure it. Semantic / Hybrid Search Configuration API is available here.
Once configuration is done, you can use the semanticSearch
input in the find
query to perform a semantic search.
query FindWithSemanticSearch { find( query: "eats carrots and is a rodent" semanticSearch: {searchBias:10, fields: ["post_title"]} ) { total documents { score data } }}
semanticSearch
is an input that accepts options used by semantic / hybrid search.searchBias: 10
is indicating that we want to use only semantic search and not full-text search. If the value is 0, only full-text search is used. If the value is between 1-9, it’s a combination of full-text and semantic search.fields: ["post_title"]
We specify that we want to perform a semantic search on thepost_title
field. (This field should be configured for semantic search in the configuration step)
Sample output from executing the graphql query above:
{ "data": { "find": { "total": 2, "documents": [ { "score": 2.209324, "data": { "ID": 6, "fieldGroup1": { "field1": null, "field2": 0 }, "history": { "owners": null }, "post_content": "", "post_date_gmt": "2024-02-09T15:21:20", "post_excerpt": "", "post_modified_gmt": "2024-02-14T16:06:44", "post_name": "rabbit-1", "post_status": "publish", "post_title": "Rabbit-1 rabbit", "post_type": "rabbit", "testNumbers": { "test_number": 0 } } }, { "score": 2.0539768, "data": { "ID": 7, "post_content": "", "post_date_gmt": "2024-02-09T15:21:23", "post_excerpt": "", "post_modified_gmt": "2024-02-09T15:21:23", "post_name": "rabbit-2", "post_status": "publish", "post_title": "Rabbit-2", "post_type": "rabbit" } } ] } }}
Note: For a complete example of how to configure, index and use semantic search, please refer to this section.
Facets
Section titled “Facets”Faceted search is a way to navigate large sets of data by aggregating terms and/or ranges, and then applying filters based on the results to narrow down a search.
Consider the following query:
{ find( query: "my search query" aggregate: { terms: [{field: "categories.name"}] } ) { total aggregations { terms { field terms { term count } } } }}
aggregate
is an input that accepts a list of terms or rangesterms: [{field: "categories.name"}]
is indicating that we want to aggregate on the fieldcategories.name
- We also specify to return the terms aggregations in the query
Sample output from executing the graphql query above:
{ "find": { "aggregations": { "terms": [ { "field": "categories.name", "terms": [ { "count": 5, "term": "sport" }, { "count": 4, "term": "farming" }, { "count": 5, "term": "shopping" } ] } ] }, "total": 14 }}
- The output of the query returns unique terms that occur in the field
categories.name
term
is the instance of the term.count
is the ammount of occurences of the term.- The
total
indicates how many documents were considered for the given search query “my search query”
Lets filter the results and select documents where categories.name
are equal to sport
{ find( query: "my search query AND categories.name:sport" aggregate: { terms: [{field: "categories.name"}] } ) { total aggregations { terms { field terms { term count } } } }}
Result:
{ "find": { "aggregations": { "terms": [ { "field": "categories.name", "terms": [ { "count": 5, "term": "sport" } ] } ] }, "total": 5 }}
For the example above we didn’t include the found documents, lets do that now.
{ find( query: "my search query AND categories.name:sport" aggregate: { terms: [{field: "categories.name"}] } ) { total aggregations { terms { field terms { term count } } } documents { data } }}
Result:
{ "find": { "documents": [ { "id": "post:2", "data": { "ID": 2, "categories": { "name": "sport" }, "post_title": "Search with aggregations query example", "post_type": "post" } } // 4 more documents ], "aggregations": { "terms": [ { "field": "categories.name", "terms": [ { "count": 5, "term": "sport" } ] } ] }, "total": 5 }}
Ranges
Section titled “Ranges”Consider the following query:
{ find( query: "*" aggregate: { ranges: [{ field: "prices.price" ranges: [ { from: 0, to: 100 }, { from: 101, to: 200 } ] }] } ) { total documents { data } aggregations { ranges { field ranges { from to count } } } }}
aggregate
is an input that accepts a list of terms or rangesranges: [{field: "prices.price" ...]
is indicating that we want to return the range on the fieldprices.name
- We then specify the ranges we want, in this example we want to bucket ranges from
0-100
and101-200
Sample output from executing the graphql query above:
{ "data": { "find": { "total": 5, "documents": [ { "data": { "post_title": "price fifty", "prices": { "price": 50 } } }, { "data": { "post_title": "price sixty", "prices": { "price": 60 } } }, { "data": { "post_title": "price seventy", "prices": { "price": 70 } } }, { "data": { "post_title": "price one hundred and twenty", "prices": { "price": 120 } } }, { "data": { "post_title": "price one hundred and fifty", "prices": { "price": 150 } } } ], "aggregations": { "ranges": [ { "field": "prices.price", "ranges": [ { "from": 0, "to": 100, "count": 3 }, { "from": 101, "to": 200, "count": 2 } ] } ] } } }}
- The output of the query returns range aggregations counting documents that match each range that occur in the field
prices.prices
from
designates the start of a range bucket.to
designates the end of a range bucketcount
is the ammount of occurences of the doucments in the specified range.- The
total
indicates how many documents were considered for the given search query ”*”
Lets update the query to filter out prices less than 100
:
{ find( query: "prices.price:>100" aggregate: { ranges: [{ field: "prices.price" ranges: [ { from: 0, to: 100 }, { from: 101, to: 200 } ] }] } ) { total aggregations { ranges { field ranges { from to count } } } }}
Sample output:
{ "data": { "find": { "total": 2, "documents": [ { "data": { "post_title": "price one hundred and twenty", "prices": { "price": 120 } } }, { "data": { "post_title": "price one hundred and fifty", "prices": { "price": 150 } } } ], "aggregations": { "ranges": [ { "field": "prices.price", "ranges": [ { "from": 0, "to": 100, "count": 0 }, { "from": 101, "to": 200, "count": 2 } ] } ] } } }}
API Reference
Section titled “API Reference”The schema defines the GraphQL query type for searching documents in an index. It includes various parameters to customize the search query.
Field | Description |
---|---|
find | Searches for documents in an index based on specific parameters. |
Find Parameters
Section titled “Find Parameters”Parameter | Type | Description |
---|---|---|
query | String! | The search query. This is required. |
filter | String | Filter string that will be added to the search query and filter out search results. |
orderBy | [OrderBy] | Used for ordering the search results. By default, a weight policy is applied. |
searchAfter | [String!] | Results offset used for cursor pagination. |
offset | Int | Results offset used for pagination. |
limit | Int | Results limit used for pagination. |
fields | [SearchField] | Specifies the fields to search for in the documents. |
tolerance | SearchOption = \{ name: stemming \} | Selects either Fuzzy or Stemming search option. By default, find will use stemming. |
meta | MetaInput | Optional meta data. |
aggregate | AggregateInput | Aggregation support. |
semanticSearch | SemanticSearchInput | Semantic Search query input. |
SearchField Input
Section titled “SearchField Input”Field | Type | Description |
---|---|---|
name | String! | The field name to search for in the document. |
weight | Int | The weight of the field, affecting the order of returned documents. |
MetaInput
Section titled “MetaInput”Optional meta data input for logging
Field | Type | Description |
---|---|---|
action | String | Performed action e.g. index |
system | String | The requester system name |
source | String | The requester hostname |
AggregateInput
Section titled “AggregateInput”Field | Type | Description |
---|---|---|
terms | [TermAggregateInput] | Aggregation based on terms. |
ranges | [RangeAggregateInput] | Aggregation based on ranges. |
TermAggregateInput
Section titled “TermAggregateInput”Field | Type | Description |
---|---|---|
field | String! | Field name we want to aggregate on |
size | Int | To retrieve additional terms, employ the "size" parameter. By default, the terms aggregation fetches the top ten terms with the highest document counts. |
minCount | Int | If minCount is zero, zero count results are returned (else we omit them) |
RangeAggregateInput
Section titled “RangeAggregateInput”Field | Type | Description |
---|---|---|
field | String! | Field name we want to aggregate on |
ranges | [RangeInput] | Range Input options |
size | Int | To retrieve additional terms, employ the "size" parameter. By default, the terms aggregation fetches the top ten terms with the highest document counts. |
RangeInput
Section titled “RangeInput”A multi-bucket value source based aggregation that enables the user to define a set of ranges - each representing a bucket
Field | Type | Description |
---|---|---|
to | Float | From value (Inclusive) |
from | Float | To value (Exclusive) |
OrderBy Input
Section titled “OrderBy Input”Field | Type | Description |
---|---|---|
field | String! | The field to order the documents by. |
direction | OrderByDirection | The sort direction (asc or desc). |
unmappedType | String | Deprecated: Going to be removed soon. When its present default weight score is applied for ordering |
SearchOption Input
Section titled “SearchOption Input”Field | Type | Description |
---|---|---|
name | SearchOptionEnum! | The search option name (fuzzy or stemming). |
fuzzyDistance | Int | Optional fuzzy distance. Applicable only if the fuzzy search option is selected. It represents the number of one-character changes needed to turn one term into another. |
SemanticSearchInput
Section titled “SemanticSearchInput”Semantic Search query input
Field | Type | Description |
---|---|---|
searchBias | Int! | The search bias of the semantic search query vs full text search - 0 = Full text search only, 10 = Semantic search only - 1-9 mix of both weighted respectfully |
fields | [String!]! | Fields for search |
type | SEMANTIC_SEARCH_TYPE | Semantic Search type |
SearchResult Type
Section titled “SearchResult Type”Field | Type | Description |
---|---|---|
total | Int | The total number of documents returned. |
documents | [SearchDocument] | The list of documents matching the search. |
SearchDocument Type
Section titled “SearchDocument Type”Field | Type | Description |
---|---|---|
id | ID! | The Search ID of the document. |
score | Float | The Search score of the document. |
sort | [String] | Values used to sort documents. Can be used in combination with searchAfter for cursor pagination. |
data | Map! | The document data. |
Enumerations
Section titled “Enumerations”SearchOptionEnum
Section titled “SearchOptionEnum”Name | Description |
---|---|
fuzzy | The fuzzy search option. |
stemming | The stemming search option. |
OrderByDirection
Section titled “OrderByDirection”Name | Description |
---|---|
asc | Sort in ascending order. |
desc | Sort in descending order. |
SEMANTIC_SEARCH_TYPE
Section titled “SEMANTIC_SEARCH_TYPE”Value | Description |
---|---|
BASIC | Basic Search type |