Perform Advanced Queries

This article will show you how to perform advanced queries using the $prismic object. To learn how to pass this content from these advanced queries to the Slice Zone component read here.


In our previous article on querying, we introduced you to three helper functions:

  • $prismic.api.getSingle()
  • $prismic.api.getByUID()
  • $prismic.api.query()

On this page, we will introduce two more helper functions:

  • $prismic.api.getByID()
  • $prismic.api.getByIDs()

We'll also:

  • go deeper into $prismic.api.query() (the most powerful helper function),
  • give an overview of search predicates,
  • and give an overview of search options.


With the ID helpers

Every document in your repo has an ID assigned by Prismic, which looks like this: X9C6UxEAAJFIAuBg.

$prismic.api.getByID(ID)

You can query a single document by its ID like so:

Copy
$prismic.api.getByID('X9C6UxEAAJFIAuBg')

$prismic.api.getByIDs(arrayOfIDs)

You can query multiple documents by their IDs like so:

Copy
$prismic.api.getByIDs(['X9C6UxEAAJFIAuBg', 'X9C65hEAAEFIAuLo'])

With the query method

The query method, $prismic.api.query(), allows you to construct advanced search queries.

As its first argument, $prismic.api.query() accepts a query. An empty string will search for all documents. Otherwise, you can construct a search query with predicates. You can pass a single predicate function or an array of predicates functions. An array will perform a search for documents that match all predicates.

What is a predicate?

All Prismic queries are built on predicates. Predicates are search parameters, and Prismic has dozens of them. Each predicate specifies a comparison (such as matching, includes, greater than, less than). Most predicates accept a path (which specifies what field to examine), and a value to compare that field against.

Here's an example of a query with predicates. This query will search for all documents of type "page" that do not have the UID "about."

Copy
<script>
export default {
  name: "HelloWorld",
  async asyncData({ $prismic, params, error }) {
    const documents = await $prismic.api.query([
      // With a document type matching "page"
      $prismic.predicates.at('document.type', 'page'),
      // And without a UID matching "about"
      $prismic.predicates.at('my.page.uid', 'about')
    ])
    if (documents) {
      return { documents }
    } else {
      error({ statusCode: 404, message: 'Page not found' })
    }
  }
}
</script>

Many, (but not all) predicates take the format of:

Copy
predicate( path, value )

The predicate would be the name of the specific predicate method. The path is where you define what field to examine on each document. The value is the value to compare against.

A simple predicate looks like this:

Copy
$prismic.predicates.at('document.type', 'blog_post')

Here are some examples of paths that predicates can accept. (Note: not all predicates can accept all paths. See the predicate reference for more details.)

  • document.type
  • document.tags
  • document.id
  • my.[custom-type].[uid-field]
  • my.[custom-type].[key-text-field]
  • my.[custom-type].[select-field]
  • my.[custom-type].[number-field]
  • my.[custom-type].[date-field]

Three commonly-used predicates are at, not, and any.

The at predicate will search for an exact match. The following query will search for all documents where the document's "type" matches "blog_post."

Copy
$prismic.predicates.at('document.type', 'blog_post')

The not predicate will search for a value that does not match. The following query will search for all documents where the "type" does not match "homepage."

Copy
$prismic.predicates.not('document.type', 'homepage')

The any predicate will check for a field that matches any value in an array. The following query will search for all "product" documents where a Select field called "climate" matches "desert", "beach", or "rainforest."

Copy
$prismic.predicates.any('my.product.climate', ['desert', 'beach', 'rainforest'])

For a full list of predicates, see the predicate reference documentation.

Here are some use cases with the query method:

All documents

Use an empty query.

Copy
$prismic.api.query('')

By Custom Type

Use the at predicate with the path document.type:

Copy
$prismic.api.query(
  $prismic.predicates.at('document.type', 'article')
)

By tag

Use the at predicate with document.tags, and put your tag in an array:

Copy
$prismic.api.query(
  $prismic.predicates.at('document.tags', ['lesson'])
);

To match multiple tags on a document, put the tags in the tags array:

Copy
$prismic.api.query(
  $prismic.predicates.at('document.tags', ['lesson', 'tutorial'])
);

To match documents that have at least one tag from an array of tags, use the any predicate:

Copy
$prismic.api.query(
  $prismic.predicates.any('document.tags', ['lesson', 'tutorial'])
);

By Date

To query content based on a specific date, use the at predicate with a Date field:

Copy
$prismic.api.query(
  $prismic.predicates.at('my.author.birthday', '2020-06-20')
)

There are many predicates specifically for building date-based queries. See them all in the Rest API Technical Reference.

To query content based on a specific month and/or year, use the month and/or year predicates. This query will search for authors with a "birthday" value within May, 2020:

Copy
$prismic.api.query([
  $prismic.predicates.month('my.author.birthday', 'May'),
  $prismic.predicates.year('my.author.birthday', 2020)
])

Documents also have first_publication_date and last_publication_date properties, which can be used with date queries. This query will search for all blog posts published in May, 2020:

Copy
$prismic.api.query([
  $prismic.predicates.at('document.type', 'blog_post'),
  $prismic.predicates.month('document.first_publication_date', 'May'),
  $prismic.predicates.year('document.first_publication_date', 2020)
])

By a Content Relationship

Content Relationships can be used to create content taxonomies. To query by Content Relationship, use the at predicate with the path my.[custom-type].[content-relationship-field] and the ID of the linked document:

Copy
$prismic.api.query([
  $prismic.predicates.at('my.blog_post.category', 'WNje3SUAAEGBu8bc')
])

Note: To query by Content Relationship, you must use the linked document's ID. The ID is a randomly-generated string that looks like this: WNje3SUAAEGBu8bc. You can find it in the metadata of document's API result.

Here's how to query by a Content Relationship with a Group:

By a field within a Group

In the following example, a blog post can have multiple categories. The search looks for documents that have one category within a group of categories that match the given ID.

Copy
$prismic.api.query(
  $prismic.predicates.at('my.blog_post.categories.category', 'WNje3SUAAEGBu8bc')
)

Query Options

All query methods can accept an options object as a subsequent argument. Some useful options are:

  • language
  • ordering
  • page
  • pageSize
  • fetchLinks

For more information on query options, see the Rest API reference.

The following query will search for all articles in the locale "en-us", ordered by the date they were last updated. It will put ten results on a page, and return the second page of results. It will also include the "bio" field of any documents of type "author" that are linked on the results.

Copy
document = await $prismic.api.query(
  $prismic.predicates.at('document.type', 'article'),
  {
    lang: 'en-us',
    orderings: '[document.last_publication_date]',
    page: 2,
    pageSize: 10,
    fetchLinks: 'author.bio'
  }
)

Query Callbacks

After the options object, all query methods can also accept a callback function as a subsequent argument. The callback function receives an error as the first argument and the API response as its second argument.

Copy
$prismic.api.query(
  $prismic.predicates.at('document.type', 'article'),
  { lang: 'en-us' },
  ( error, document ) => error ? console.log(error) : console.log(document)
)

Related Articles


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.