docs: improves queries docs (#7122)

This commit is contained in:
Jacob Fletcher
2024-07-11 17:49:54 -04:00
committed by GitHub
parent 840e07577e
commit fac5425ec0
13 changed files with 218 additions and 241 deletions

94
docs/queries/depth.mdx Normal file
View File

@@ -0,0 +1,94 @@
---
title: Depth
label: Depth
order: 30
desc: Payload depth determines how many levels down related documents should be automatically populated when retrieved.
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Documents in Payload can have relationships to other Documents. This is true for both [Collections](../configuration/collections) as well as [Globals](../configuration/globals). When you query a Document, you can specify the depth at which to populate any of its related Documents as full objects, or simply return their Document IDs.
Depth will optimize the performance of your application by limiting the number of queries made to the database, and significantly reducing the amount of data returned. Since Documents can be infinitely nested or recursively related, it's important to be able to control how deep your API populate.
When you specify a `depth` of `0`, for example, the API response might look like this:
```json
{
"id": "5ae8f9bde69e394e717c8832",
"title": "This is a great post",
"author": "5f7dd05cd50d4005f8bcab17"
}
```
But with a `depth` of `1`, the response might look like this:
```json
{
"id": "5ae8f9bde69e394e717c8832",
"title": "This is a great post",
"author": {
"id": "5f7dd05cd50d4005f8bcab17",
"name": "John Doe"
}
}
```
<Banner type="warning">
<strong>Important:</strong>
Depth has no effect in the [GraphQL API](../graphql/overview), because there, depth is based on the shape of your queries.
</Banner>
## Local API
To specify depth in the [Local API](../local-api/overview), you can use the `depth` option in your query:
```ts
const getPosts = async () => {
const posts = await payload.find({
collection: 'posts',
depth: 2, // highlight-line
})
return posts
}
```
<Banner type="info">
<strong>Reminder:</strong>
This is the same for [Globals](../configuration/globals) using the `findGlobal` operation.
</Banner>
## REST API
To specify depth in the [REST API](../rest-api/overview), you can use the `depth` parameter in your query:
```ts
fetch('https://localhost:3000/api/posts?depth=2') // highlight-line
.then((response) => response.json())
.then((data) => console.log(data))
```
<Banner type="info">
<strong>Reminder:</strong>
This is the same for [Globals](../configuration/globals) using the `/api/globals` endpoint.
</Banner>
## Max Depth
Fields like the [Relationship Field](../fields/relationship) or the [Upload Field](../fields/upload) can also set a maximum depth. If exceeded, this will limit the population depth regardless of the depth of the request.
To set a max depth for a field, use the `maxDepth` property in your field configuration:
```js
{
slug: 'posts',
fields: [
{
name: 'author',
type: 'relationship',
relationTo: 'users',
maxDepth: 2, // highlight-line
}
]
}
```

View File

@@ -6,54 +6,37 @@ desc: Payload provides a querying language through all APIs, allowing you to fil
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.
In Payload, "querying" means filtering or searching through Documents within a [Collection](../configuration/collections). The querying language in Payload is designed to be simple and powerful, allowing you to filter documents with extreme precision.
<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>
Payload provides three common APIs for querying your data:
## Simple queries
- [Local API](/docs/local-api/overview) - Extremely fast, direct-to-database access
- [REST API](/docs/rest-api/overview) - Standard HTTP endpoints for querying and mutating data
- [GraphQL](/docs/graphql/overview) - A full GraphQL API with a GraphQL Playground
For example, say you have a collection as follows:
Each of these APIs share the same underlying querying language, and fully support all of the same features. This means that you can learn Payload's querying language once, and use it across any of the APIs that you might use.
To query your Documents, you can send any number of [Operators](#operators) through your request:
```ts
import { CollectionConfig } from 'payload'
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
equals: 'blue',
},
}
```
The above example demonstrates a simple query but you can get much more complex.
_The exact query syntax will depend on the API you are using, but the concepts are the same across all APIs. [More details](#writing-queries)._
<Banner>
<strong>Tip:</strong>
You can also use queries within [Access Control](../access-control/overview) functions.
</Banner>
## Operators
The following operators are available for use in queries:
| Operator | Description |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `equals` | The value must be exactly equal. |
@@ -68,31 +51,29 @@ The above example demonstrates a simple query but you can get much more complex.
| `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)>`. |
| `near` | For distance related to a [Point Field](../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.
<strong>Tip:</strong>
If you know your users will be querying on certain fields a lot, add `index: true` to the Field Config. This will speed up searches using that field immensely.
</Banner>
## And / Or Logic
### 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:
In addition to defining simple queries, you can join multiple queries together using AND / OR logic. These can be nested as deeply as you need to create complex queries.
```js
To join queries, use the `and` or `or` keys in your query object:
```ts
const query = {
or: [
// array of OR conditions
or: [ // highlight-line
{
color: {
equals: 'mint',
},
},
{
and: [
// nested array of AND conditions
and: [ // highlight-line
{
color: {
equals: 'white',
@@ -111,7 +92,7 @@ const query = {
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
### 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:
@@ -124,13 +105,34 @@ const query = {
}
```
## GraphQL Find Queries
## Writing Queries
All GraphQL `find` queries support the `where` argument, which accepts queries exactly as detailed above.
Writing queries in Payload is simple and consistent across all APIs, with only minor differences in syntax between them.
**For example:**
### Local API
The [Local API](../local-api/overview) supports the `find` operation that accepts a raw query object:
```ts
const getPosts = async () => {
const posts = await payload.find({
collection: 'posts',
where: {
color: {
equals: 'mint',
},
},
})
return posts
}
```
### GraphQL API
All `find` queries in the [GraphQL API](../graphql/overview) support the `where` argument that accepts a raw query object:
```ts
query {
Posts(where: { color: { equals: mint } }) {
docs {
@@ -141,19 +143,17 @@ query {
}
```
## REST Queries
### REST API
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:
With the [REST API](../rest-api/overview), you can use the full power of Payload queries, but they are written as query strings instead:
**`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.
To understand the syntax, you need to understand that complex URL search strings are parsed into a JSON object. This one isn't too bad, but more complex queries get unavoidably more difficult to write.
**For example, using fetch:**
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:
```js
```ts
import { stringify } from 'qs-esm'
const query = {
@@ -176,54 +176,3 @@ const getPosts = async () => {
// 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
}
```

View File

@@ -1,7 +1,7 @@
---
title: Pagination
label: Pagination
order: 20
order: 40
desc: Payload queries are equipped with automatic pagination so you create paginated lists of documents within your app.
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---

55
docs/queries/sort.mdx Normal file
View File

@@ -0,0 +1,55 @@
---
title: Sort
label: Sort
order: 20
desc: Payload sort allows you to order your documents by a field in ascending or descending order.
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
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.
<Banner type="success">
<strong>Tip:</strong>
A minus symbol ("-") before the field name will sort in descending order. Omitting the minus symbol will sort in ascending order.
</Banner>
## Local API
To sort Documents in the [Local API](../local-api/overview), you can use the `sort` option in your query:
```ts
const getPosts = async () => {
const posts = await payload.find({
collection: 'posts',
sort: '-createdAt', // highlight-line
})
return posts
}
```
## REST API
To sort in the [REST API](../rest-api/overview), you can use the `sort` parameter in your query:
```ts
fetch('https://localhost:3000/api/posts?sort=-createdAt') // highlight-line
.then((response) => response.json())
.then((data) => console.log(data))
```
## GraphQL API
To sort in the [GraphQL API](../graphql/overview), you can use the `sort` parameter in your query:
```ts
query {
Posts(sort: "-createdAt") {
docs {
color
}
}
}
```