Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Querying your Documents

Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.

Simple queries

For example, say you have a collection as follows:

1
import { CollectionConfig } from 'payload/types'
2
3
export const Post: CollectionConfig = {
4
slug: 'posts',
5
fields: [
6
{
7
name: 'color',
8
type: 'select',
9
options: ['mint', 'dark-gray', 'white'],
10
},
11
{
12
name: 'featured',
13
type: 'checkbox',
14
},
15
],
16
}

You may eventually have a lot of documents within this Collection. If you wanted to find only documents with color equal to mint, you could write a query as follows:

1
const query = {
2
color: {
3
// property name to filter on
4
equals: 'mint', // operator to use and value to compare against
5
},
6
}

The above example demonstrates a simple query but you can get much more complex.

Operators

OperatorDescription
equalsThe value must be exactly equal.
not_equalsThe query will return all documents where the value is not equal.
greater_thanFor numeric or date-based fields.
greater_than_equalFor numeric or date-based fields.
less_thanFor numeric or date-based fields.
less_than_equalFor numeric or date-based fields.
likeCase-insensitive string must be present. If string of words, all words must be present, in any order.
containsMust contain the value entered, case-insensitive.
inThe value must be found within the provided comma-delimited list of values.
not_inThe value must NOT be within the provided comma-delimited list of values.
allThe value must contain all values provided in the comma-delimited list.
existsOnly return documents where the value either exists (true) or does not exist (false).
nearFor distance related to a point field comma separated as <longitude>, <latitude>, <maxDistance in meters (nullable)>, <minDistance in meters (nullable)>.

And / Or Logic

In addition to defining simple queries, you can join multiple queries together using simple AND / OR logic. Let's take the above Post collection for example and write a more complex query using AND / OR:

1
const query = {
2
or: [
3
// array of OR conditions
4
{
5
color: {
6
equals: 'mint',
7
},
8
},
9
{
10
and: [
11
// nested array of AND conditions
12
{
13
color: {
14
equals: 'white',
15
},
16
},
17
{
18
featured: {
19
equals: false,
20
},
21
},
22
],
23
},
24
],
25
}

Written in plain English, if the above query were passed to a find operation, it would translate to finding posts where either the color is mint OR the color is white AND featured is set to false.

Nested properties

When working with nested properties, which can happen when using relational fields, it is possible to use the dot notation to access the nested property. For example, when working with a Song collection that has a artists field which is related to an Artists collection using the name: 'artists'. You can access a property within the collection Artists like so:

1
const query = {
2
'artists.featured': {
3
// nested property name to filter on
4
exists: true, // operator to use and boolean value that needs to be true
5
},
6
}

GraphQL Find Queries

All GraphQL find queries support the where argument, which accepts queries exactly as detailed above.

For example:

1
query {
2
Posts(where: { color: { equals: mint } }) {
3
docs {
4
color
5
}
6
totalDocs
7
}
8
}

REST Queries

With the REST API, you can use the full power of Payload queries as well but they become a bit more unwieldy the more complex that they get.

Simple queries are fairly straightforward to write. To understand the syntax, you need to understand how Express and similar languages would go about parsing a complex URL search string into a JSON object. For example, the above simple query would be parsed into a string like this:

https://localhost:3000/api/posts?where[color][equals]=mint

This one isn't too bad, but more complex queries get unavoidably more difficult to write as query strings. For this reason, we recommend to use the extremely helpful and ubiquitous qs package to parse your JSON / object-formatted queries into query strings for use with the REST API.

For example, using fetch:

1
import qs from 'qs'
2
3
const query = {
4
color: {
5
equals: 'mint',
6
},
7
// This query could be much more complex
8
// and QS would handle it beautifully
9
}
10
11
const getPosts = async () => {
12
const stringifiedQuery = qs.stringify(
13
{
14
where: query, // ensure that `qs` adds the `where` property, too!
15
},
16
{ addQueryPrefix: true },
17
)
18
19
const response = await fetch(`http://localhost:3000/api/posts${stringifiedQuery}`)
20
// Continue to handle the response below...
21
}

Local API Queries

The Local API's find operation accepts an object exactly how you write it. For example:

1
const getPosts = async () => {
2
const posts = await payload.find({
3
collection: 'posts',
4
where: {
5
color: {
6
equals: 'mint',
7
},
8
},
9
})
10
11
return posts
12
}

Sort

Payload find queries support a sort parameter through all APIs. Pass the name of a top-level field to sort by that field in ascending order. Prefix the name of the field with a minus symbol ("-") to sort in descending order. Because sorting is handled by the database, the field you wish to sort on must be stored in the database to work; not a virtual field. It is recommended to enable indexing for the fields where sorting is used.

REST example: https://localhost:3000/api/posts?sort=-createdAt

GraphQL example:

1
query {
2
Posts(sort: "-createdAt") {
3
docs {
4
color
5
}
6
}
7
}

Local API example:

1
const getPosts = async () => {
2
const posts = await payload.find({
3
collection: 'posts',
4
sort: '-createdAt',
5
})
6
7
return posts
8
}
Next

Pagination