230 lines
8.9 KiB
Plaintext
230 lines
8.9 KiB
Plaintext
---
|
|
title: Querying your Documents
|
|
label: Overview
|
|
order: 10
|
|
desc: Payload provides a querying language through all APIs, allowing you to filter or search through documents within a Collection.
|
|
keywords: query, documents, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
|
---
|
|
|
|
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
|
|
|
|
<Banner>
|
|
<strong>
|
|
Here, "querying" relates to filtering or searching through documents within a Collection.
|
|
</strong>
|
|
You can build queries to pass to Find operations as well as to [restrict which documents certain
|
|
users can [access](/docs/access-control/overview) via access control functions.
|
|
</Banner>
|
|
|
|
## Simple queries
|
|
|
|
For example, say you have a collection as follows:
|
|
|
|
```ts
|
|
import { CollectionConfig } from 'payload/types'
|
|
|
|
export const Post: CollectionConfig = {
|
|
slug: 'posts',
|
|
fields: [
|
|
{
|
|
name: 'color',
|
|
type: 'select',
|
|
options: ['mint', 'dark-gray', 'white'],
|
|
},
|
|
{
|
|
name: 'featured',
|
|
type: 'checkbox',
|
|
},
|
|
],
|
|
}
|
|
```
|
|
|
|
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:
|
|
|
|
```js
|
|
const query = {
|
|
color: {
|
|
// property name to filter on
|
|
equals: 'mint', // operator to use and value to compare against
|
|
},
|
|
}
|
|
```
|
|
|
|
The above example demonstrates a simple query but you can get much more complex.
|
|
|
|
## Operators
|
|
|
|
| Operator | Description |
|
|
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `equals` | The value must be exactly equal. |
|
|
| `not_equals` | The query will return all documents where the value is not equal. |
|
|
| `greater_than` | For numeric or date-based fields. |
|
|
| `greater_than_equal` | For numeric or date-based fields. |
|
|
| `less_than` | For numeric or date-based fields. |
|
|
| `less_than_equal` | For numeric or date-based fields. |
|
|
| `like` | Case-insensitive string must be present. If string of words, all words must be present, in any order. |
|
|
| `contains` | Must contain the value entered, case-insensitive. |
|
|
| `in` | The value must be found within the provided comma-delimited list of values. |
|
|
| `not_in` | The value must NOT be within the provided comma-delimited list of values. |
|
|
| `all` | The value must contain all values provided in the comma-delimited list. |
|
|
| `exists` | Only return documents where the value either exists (`true`) or does not exist (`false`). |
|
|
| `near` | For distance related to a [point field](/docs/fields/point) comma separated as `<longitude>, <latitude>, <maxDistance in meters (nullable)>, <minDistance in meters (nullable)>`. |
|
|
|
|
<Banner type="success">
|
|
<strong>Tip</strong>:<br />
|
|
If you know your users will be querying on certain fields a lot, you can add <strong>
|
|
index: true
|
|
</strong> to a field's config which will speed up searches using that field immensely.
|
|
</Banner>
|
|
|
|
## 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:
|
|
|
|
```js
|
|
const query = {
|
|
or: [
|
|
// array of OR conditions
|
|
{
|
|
color: {
|
|
equals: 'mint',
|
|
},
|
|
},
|
|
{
|
|
and: [
|
|
// nested array of AND conditions
|
|
{
|
|
color: {
|
|
equals: 'white',
|
|
},
|
|
},
|
|
{
|
|
featured: {
|
|
equals: false,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
```
|
|
|
|
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:
|
|
|
|
```js
|
|
const query = {
|
|
'artists.featured': {
|
|
// nested property name to filter on
|
|
exists: true, // operator to use and boolean value that needs to be true
|
|
},
|
|
}
|
|
```
|
|
|
|
## GraphQL Find Queries
|
|
|
|
All GraphQL `find` queries support the `where` argument, which accepts queries exactly as detailed above.
|
|
|
|
**For example:**
|
|
|
|
```
|
|
query {
|
|
Posts(where: { color: { equals: mint } }) {
|
|
docs {
|
|
color
|
|
}
|
|
totalDocs
|
|
}
|
|
}
|
|
```
|
|
|
|
## 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 that complex URL search strings are parsed into a JSON object. For example, the above [simple query](#simple-queries) 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`](https://www.npmjs.com/package/qs) package to parse your JSON / object-formatted queries into query strings for use with the REST API.
|
|
|
|
**For example, using fetch:**
|
|
|
|
```js
|
|
import qs from 'qs'
|
|
|
|
const query = {
|
|
color: {
|
|
equals: 'mint',
|
|
},
|
|
// This query could be much more complex
|
|
// and QS would handle it beautifully
|
|
}
|
|
|
|
const getPosts = async () => {
|
|
const stringifiedQuery = qs.stringify(
|
|
{
|
|
where: query, // ensure that `qs` adds the `where` property, too!
|
|
},
|
|
{ addQueryPrefix: true },
|
|
)
|
|
|
|
const response = await fetch(`http://localhost:3000/api/posts${stringifiedQuery}`)
|
|
// Continue to handle the response below...
|
|
}
|
|
```
|
|
|
|
## Local API Queries
|
|
|
|
The Local API's `find` operation accepts an object exactly how you write it. For example:
|
|
|
|
```js
|
|
const getPosts = async () => {
|
|
const posts = await payload.find({
|
|
collection: 'posts',
|
|
where: {
|
|
color: {
|
|
equals: 'mint',
|
|
},
|
|
},
|
|
})
|
|
|
|
return posts
|
|
}
|
|
```
|
|
|
|
## 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](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges). It is recommended to enable indexing for the fields where sorting is used.
|
|
|
|
**REST example:**
|
|
**`https://localhost:3000/api/posts?sort=-createdAt`**
|
|
|
|
**GraphQL example:**
|
|
|
|
```
|
|
query {
|
|
Posts(sort: "-createdAt") {
|
|
docs {
|
|
color
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Local API example:**
|
|
|
|
```js
|
|
const getPosts = async () => {
|
|
const posts = await payload.find({
|
|
collection: 'posts',
|
|
sort: '-createdAt',
|
|
})
|
|
|
|
return posts
|
|
}
|
|
```
|