docs: improves queries docs (#7122)
This commit is contained in:
@@ -6,12 +6,10 @@ desc: Structure your Collections for your needs by defining fields, adding slugs
|
|||||||
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||||
---
|
---
|
||||||
|
|
||||||
A Collection is a group of records, called Documents, that share a common schema. You can define as many Collections as your application needs. Each Collection saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define.
|
A Collection is a group of records, called Documents, that share a common schema. You can define as many Collections as your application needs. Each Collection saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates the [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) so you can query and mutate your Documents.
|
||||||
|
|
||||||
Collections are the primary way to structure recurring data in your application, such as users, products, pages, posts, and other types of content that you might want to manage. Each Collection can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
|
Collections are the primary way to structure recurring data in your application, such as users, products, pages, posts, and other types of content that you might want to manage. Each Collection can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
|
||||||
|
|
||||||
All Collections automatically accessible through the [Local API](../local-api/overview). If your application is using the [Admin Panel](../admin/overview), you will also get a fully-featured [REST API](../rest-api/overview) and [GraphQL API](../graphql/overview) without any additional configuration.
|
|
||||||
|
|
||||||
To define a Collection Config, use the `collection` property in your [Payload Config](./overview):
|
To define a Collection Config, use the `collection` property in your [Payload Config](./overview):
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ desc: Set up your Global config for your needs by defining fields, adding slugs
|
|||||||
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||||
---
|
---
|
||||||
|
|
||||||
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. You can define as many Globals as your application needs. Each Global saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define.
|
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. You can define as many Globals as your application needs. Each Global saves to the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates the [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) so you can query and mutate your Documents.
|
||||||
|
|
||||||
Globals are the primary way to structure singletons in Payload, such as a header navigation, site-wide banner alerts, or app-wide localized strings. Each Global can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
|
Globals are the primary way to structure singletons in Payload, such as a header navigation, site-wide banner alerts, or app-wide localized strings. Each Global can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
|
||||||
|
|
||||||
All Globals are automatically accessible through the [Local API](../local-api/overview). If your application is using the [Admin Panel](../admin/overview), you will also get a fully-featured [REST API](../rest-api/overview) and [GraphQL API](../graphql/overview) without any additional configuration.
|
|
||||||
|
|
||||||
To define a Global Config, use the `globals` property in your [Payload Config](./overview):
|
To define a Global Config, use the `globals` property in your [Payload Config](./overview):
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ The following options are available:
|
|||||||
| **`graphQL`** | Manage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. [More details](../graphql/overview#graphql-options). |
|
| **`graphQL`** | Manage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. [More details](../graphql/overview#graphql-options). |
|
||||||
| **`cookiePrefix`** | A string that will be prefixed to all cookies that Payload sets. |
|
| **`cookiePrefix`** | A string that will be prefixed to all cookies that Payload sets. |
|
||||||
| **`csrf`** | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More details](../authentication/overview#csrf-protection). |
|
| **`csrf`** | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More details](../authentication/overview#csrf-protection). |
|
||||||
| **`defaultDepth`** | If a user does not specify `depth` while requesting a resource, this depth will be used. [More details](../getting-started/concepts#depth). |
|
| **`defaultDepth`** | If a user does not specify `depth` while requesting a resource, this depth will be used. [More details](../queries/depth). |
|
||||||
| **`defaultMaxTextLength`** | The maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation. |
|
| **`defaultMaxTextLength`** | The maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation. |
|
||||||
| **`maxDepth`** | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
| **`maxDepth`** | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
||||||
| **`indexSortableFields`** | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
| **`indexSortableFields`** | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ _\* An asterisk denotes that a property is required._
|
|||||||
<Banner type="success">
|
<Banner type="success">
|
||||||
<strong>Tip:</strong>
|
<strong>Tip:</strong>
|
||||||
<br />
|
<br />
|
||||||
The [Depth](/docs/getting-started/concepts#depth) parameter can be used to automatically populate
|
The [Depth](../queries/depth) parameter can be used to automatically populate
|
||||||
related documents that are returned by the API.
|
related documents that are returned by the API.
|
||||||
</Banner>
|
</Banner>
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
|
|||||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||||
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
|
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
|
||||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
|
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
|
||||||
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](/docs/getting-started/concepts#depth) |
|
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](../queries/depth) |
|
||||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||||
|
|||||||
@@ -129,125 +129,7 @@ If you don't use GraphQL, you can delete those files! But if you do, you'll find
|
|||||||
|
|
||||||
## Depth
|
## Depth
|
||||||
|
|
||||||
<Banner type="info">
|
Documents can be related to other Documents through a concept called "relationships". When you query a Document, you can specify these relationships are populated. [More details](../queries/depth).
|
||||||
"Depth" gives you control over how many levels down related documents should be automatically
|
|
||||||
populated when retrieved.
|
|
||||||
</Banner>
|
|
||||||
|
|
||||||
You can specify population `depth` via query parameter in the REST API and by an option in the local API. _Depth has no effect in the GraphQL API, because there, depth is based on the shape of your queries._
|
|
||||||
It is also possible to limit the depth for specific `relation` and `upload` fields using the `maxDepth` property in your configuration.
|
|
||||||
**For example, let's look at the following Collections:** `departments`, `users`, `posts`
|
|
||||||
|
|
||||||
```
|
|
||||||
// type: 'relationship' fields are equal to 1 depth level
|
|
||||||
|
|
||||||
{
|
|
||||||
slug: 'posts',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'title',
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'author',
|
|
||||||
label: 'Post Author',
|
|
||||||
type: 'relationship',
|
|
||||||
relationTo: 'users',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
slug: 'users',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'email',
|
|
||||||
type: 'email',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'department'
|
|
||||||
type: 'relationship',
|
|
||||||
relationTo: 'departments'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
slug: 'departments',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'name'
|
|
||||||
type: 'text',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you were to query the Posts endpoint at, say, `http://localhost:3000/api/posts?depth=1`, you will retrieve Posts with populations one level deep. This depth parameter can be thought of as N, where N is the number of levels you want to populate. To populate one level further, you would simply specify N+1 as the depth. A returned result may look like the following:
|
|
||||||
|
|
||||||
```
|
|
||||||
// ?depth=1
|
|
||||||
|
|
||||||
{
|
|
||||||
id: '5ae8f9bde69e394e717c8832',
|
|
||||||
title: 'This post sucks',
|
|
||||||
author: {
|
|
||||||
id: '5f7dd05cd50d4005f8bcab17',
|
|
||||||
email: 'spiderman@superheroes.gov',
|
|
||||||
department: '5e3ca05cd50d4005f8bdab15'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Notice how the `user.author` is fully populated, but `user.author.department` is left as a document ID? That's because the User collection counted as the first level of `depth` and got populated—but then prevented any further populations from taking place.
|
|
||||||
|
|
||||||
To populate `user.author.department` in it's entirety you could specify `?depth=2` or _higher_.
|
|
||||||
|
|
||||||
```
|
|
||||||
// ?depth=2
|
|
||||||
|
|
||||||
{
|
|
||||||
id: '5ae8f9bde69e394e717c8832',
|
|
||||||
title: 'This post sucks',
|
|
||||||
author: {
|
|
||||||
id: '5f7dd05cd50d4005f8bcab17',
|
|
||||||
email: 'spiderman@superheroes.gov',
|
|
||||||
department: {
|
|
||||||
id: '5e3ca05cd50d4005f8bdab15',
|
|
||||||
name: 'Marvel'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Field-level max depth
|
|
||||||
|
|
||||||
Fields like relationships or uploads can have a `maxDepth` property that limits the depth of the population for that field. Here are some examples:
|
|
||||||
|
|
||||||
Depth: 10
|
|
||||||
Current depth when field is accessed: 1
|
|
||||||
`maxDepth`: undefined
|
|
||||||
|
|
||||||
In this case, the field would be populated to 9 levels of population.
|
|
||||||
|
|
||||||
Depth: 10
|
|
||||||
Current depth when field is accessed: 0
|
|
||||||
`maxDepth`: 2
|
|
||||||
|
|
||||||
In this case, the field would be populated to 2 levels of population, despite there being a remaining depth of 8.
|
|
||||||
|
|
||||||
Depth: 10
|
|
||||||
Current depth when field is accessed: 2
|
|
||||||
`maxDepth`: 1
|
|
||||||
|
|
||||||
In this case, the field would not be populated, as the current depth (2) has exceeded the `maxDepth` for this field (1).
|
|
||||||
|
|
||||||
<Banner type="warning">
|
|
||||||
<strong>Note:</strong>
|
|
||||||
<br />
|
|
||||||
When access control on collections prevents relationship fields from populating, the API response
|
|
||||||
will contain the relationship id instead of the full document.
|
|
||||||
</Banner>
|
|
||||||
|
|
||||||
## Plugins
|
## Plugins
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ And return the following values:
|
|||||||
</Banner>
|
</Banner>
|
||||||
|
|
||||||
<Banner type="info">
|
<Banner type="info">
|
||||||
It is important that the `depth` argument matches exactly with the depth of your initial page request. The depth property is used to populated relationships and uploads beyond their IDs. See [Depth](../getting-started/concepts#depth) for more information.
|
It is important that the `depth` argument matches exactly with the depth of your initial page request. The depth property is used to populated relationships and uploads beyond their IDs. See [Depth](../queries/depth) for more information.
|
||||||
</Banner>
|
</Banner>
|
||||||
|
|
||||||
## Frameworks
|
## Frameworks
|
||||||
@@ -273,7 +273,7 @@ If you are using relationships or uploads in your front-end application, and you
|
|||||||
|
|
||||||
### Relationships and/or uploads disappear after editing a document
|
### Relationships and/or uploads disappear after editing a document
|
||||||
|
|
||||||
It is possible that either you are setting an improper [`depth`](../getting-started/concepts#depth) in your initial request and/or your `useLivePreview` hook, or they're mismatched. Ensure that the `depth` parameter is set to the correct value, and that it matches exactly in both places. For example:
|
It is possible that either you are setting an improper [`depth`](../queries/depth) in your initial request and/or your `useLivePreview` hook, or they're mismatched. Ensure that the `depth` parameter is set to the correct value, and that it matches exactly in both places. For example:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// Your initial request
|
// Your initial request
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ You can specify more options within the Local API vs. REST or GraphQL due to the
|
|||||||
| ------------------ | ------------ |
|
| ------------------ | ------------ |
|
||||||
| `collection` | Required for Collection operations. Specifies the Collection slug to operate against. |
|
| `collection` | Required for Collection operations. Specifies the Collection slug to operate against. |
|
||||||
| `data` | The data to use within the operation. Required for `create`, `update`. |
|
| `data` | The data to use within the operation. Required for `create`, `update`. |
|
||||||
| `depth` | [Control auto-population](/docs/getting-started/concepts#depth) of nested relationship and upload fields. |
|
| `depth` | [Control auto-population](../queries/depth) of nested relationship and upload fields. |
|
||||||
| `locale` | Specify [locale](/docs/configuration/localization) for any returned documents. |
|
| `locale` | Specify [locale](/docs/configuration/localization) for any returned documents. |
|
||||||
| `fallbackLocale` | Specify a [fallback locale](/docs/configuration/localization) to use for any returned documents. |
|
| `fallbackLocale` | Specify a [fallback locale](/docs/configuration/localization) to use for any returned documents. |
|
||||||
| `overrideAccess` | Skip access control. By default, this property is set to true within all Local API operations. |
|
| `overrideAccess` | Skip access control. By default, this property is set to true within all Local API operations. |
|
||||||
|
|||||||
94
docs/queries/depth.mdx
Normal file
94
docs/queries/depth.mdx
Normal 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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -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
|
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>
|
Payload provides three common APIs for querying your data:
|
||||||
<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
|
- [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
|
```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 = {
|
const query = {
|
||||||
color: {
|
color: {
|
||||||
// property name to filter on
|
equals: 'blue',
|
||||||
equals: 'mint', // operator to use and value to compare against
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
## Operators
|
||||||
|
|
||||||
|
The following operators are available for use in queries:
|
||||||
|
|
||||||
| Operator | Description |
|
| Operator | Description |
|
||||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `equals` | The value must be exactly equal. |
|
| `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. |
|
| `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. |
|
| `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`). |
|
| `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">
|
<Banner type="success">
|
||||||
<strong>Tip</strong>:<br />
|
<strong>Tip:</strong>
|
||||||
If you know your users will be querying on certain fields a lot, you can add <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.
|
||||||
index: true
|
|
||||||
</strong> to a field's config which will speed up searches using that field immensely.
|
|
||||||
</Banner>
|
</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 = {
|
const query = {
|
||||||
or: [
|
or: [ // highlight-line
|
||||||
// array of OR conditions
|
|
||||||
{
|
{
|
||||||
color: {
|
color: {
|
||||||
equals: 'mint',
|
equals: 'mint',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
and: [
|
and: [ // highlight-line
|
||||||
// nested array of AND conditions
|
|
||||||
{
|
{
|
||||||
color: {
|
color: {
|
||||||
equals: 'white',
|
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.
|
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:
|
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 {
|
query {
|
||||||
Posts(where: { color: { equals: mint } }) {
|
Posts(where: { color: { equals: mint } }) {
|
||||||
docs {
|
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.
|
With the [REST API](../rest-api/overview), you can use the full power of Payload queries, but they are written as query strings instead:
|
||||||
|
|
||||||
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`**
|
**`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'
|
import { stringify } from 'qs-esm'
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
@@ -176,54 +176,3 @@ const getPosts = async () => {
|
|||||||
// Continue to handle the response below...
|
// 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
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: Pagination
|
title: Pagination
|
||||||
label: 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.
|
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
|
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||||
---
|
---
|
||||||
|
|||||||
55
docs/queries/sort.mdx
Normal file
55
docs/queries/sort.mdx
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -10,11 +10,12 @@ keywords: rest, api, documentation, Content Management System, cms, headless, ja
|
|||||||
A fully functional REST API is automatically generated from your Collection and Global configs.
|
A fully functional REST API is automatically generated from your Collection and Global configs.
|
||||||
</Banner>
|
</Banner>
|
||||||
|
|
||||||
|
The REST API is a fully functional HTTP client that allows you to interact with your Documents in a RESTful manner. It supports all CRUD operations and is equipped with automatic pagination, depth, and sorting.
|
||||||
All Payload API routes are mounted and prefixed to your config's `routes.api` URL segment (default: `/api`).
|
All Payload API routes are mounted and prefixed to your config's `routes.api` URL segment (default: `/api`).
|
||||||
|
|
||||||
**REST query parameters:**
|
**REST query parameters:**
|
||||||
|
|
||||||
- [depth](/docs/getting-started/concepts#depth) - automatically populates relationships and uploads
|
- [depth](../queries/depth) - automatically populates relationships and uploads
|
||||||
- [locale](/docs/configuration/localization#retrieving-localized-docs) - retrieves document(s) in a specific locale
|
- [locale](/docs/configuration/localization#retrieving-localized-docs) - retrieves document(s) in a specific locale
|
||||||
- [fallback-locale](/docs/configuration/localization#retrieving-localized-docs) - specifies a fallback locale if no locale value exists
|
- [fallback-locale](/docs/configuration/localization#retrieving-localized-docs) - specifies a fallback locale if no locale value exists
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user