Perform Advanced Queries

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

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

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

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

We'll also:

  • go deeper into $prismic.client.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.client.getByID(ID)

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

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

$prismic.client.getByIDs(arrayOfIDs)

You can query multiple documents by their IDs like so:

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

With the query method

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

As its first argument, $prismic.client.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
export default {
  name: 'HelloWorld',
  data() {
    return {
      // Initialize the 'documents' object
      documents: null
    }
  },
  methods: {
    // Define your search method
    async getContent() {
      this.documents = await this.$prismic.client.query([
        // With a document type matching "page"
        this.$prismic.Predicates.at('document.type', 'page'),
        // And without a UID matching "about"
        this.$prismic.Predicates.not('my.page.uid', 'about')
      ])
      console.log(this.documents)
    }
  },
  created() {
    // Call the search method after the component loads
    this.getContent()
  }
}

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
this.$prismic.client.query('')

By Custom Type

Use the at predicate with the path document.type:

Copy
this.$prismic.client.query(
  this.$prismic.Predicates.at('document.type', 'article')
)

By tag

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

Copy
this.$prismic.client.query(
  this.$prismic.Predicates.at('document.tags', ['lesson'])
);

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

Copy
this.$prismic.client.query(
  this.$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
this.$prismic.client.query(
  this.$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
this.$prismic.client.query(
  this.$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
this.$prismic.client.query([
  this.$prismic.Predicates.month('my.author.birthday', 'May'),
  this.$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
this.$prismic.client.query([
  this.$prismic.Predicates.at('document.type', 'blog_post'),
  this.$prismic.Predicates.month('document.first_publication_date', 'May'),
  this.$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
this.$prismic.client.query([
  this.$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
this.$prismic.client.query(
  this.$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
this.document = await this.$prismic.client.query(
  this.$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
this.$prismic.client.query(
  this.$prismic.Predicates.at('document.type', 'article'),
  { lang: 'en-us' },
  ( error, document ) => error ? console.log(error) : console.log(document)
)