Skip to content
Atlas Platform
GitHubDiscordYouTube

Using GraphQL Search API

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

The Find API allows you to search for documents in an index based on specific parameters.

API Reference

The schema defines the GraphQL query type for searching documents in an index. It includes various parameters to customize the search query.

Query

Field Description
find Searches for documents in an index based on specific parameters.

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.

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.

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

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.

SearchResult Type

Field Type Description
total Int The total number of documents returned.
documents [SearchDocument] The list of documents matching the search.

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

SearchOptionEnum

Name Description
fuzzy The fuzzy search option.
stemming The stemming search option.

OrderByDirection

Name Description
asc Sort in ascending order.
desc Sort in descending order.

Basic Usage

To search for documents using the find query. Below, you can see examples:

Find query basic example

query FindSimpleQuery {
  find(query: "hello") {
    total
    documents {
      id
      score
      data
    }
  }
}

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 index
    • score is a relevance score, which determines how closely each document matches the query

Advanced Usage

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

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

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.

Cursor pagination

Search also supports cursor pagination.

Notes:

  • orderBy would need to be provided in order to avoid sort 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"
          ]
        }
      ]
    }
  }
}

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.

Terms

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 ranges
  • terms: [{field: "categories.name"}] is indicating that we want to aggregate on the field categories.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

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 ranges
  • ranges: [{field: "prices.price" ...] is indicating that we want to return the range on the field prices.name
  • We then specify the ranges we want, in this example we want to bucket ranges from 0-100 and 101-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 bucket
  • count 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
              }
            ]
          }
        ]
      }
    }
  }
}