查询文档
在 Payload 中,"querying"(查询)指的是对 Collection 中的文档进行过滤或搜索。Payload 的查询语言设计简洁而强大,通过直观且标准化的结构,让你能够极其精确地筛选文档。
Payload 提供了三种常用的数据查询 API:
- Local API - 极速直达数据库的访问方式
- REST API - 标准的 HTTP 端点,用于查询和变更数据
- GraphQL - 完整的 GraphQL API,附带 GraphQL Playground
这些 API 都共享相同的底层查询语言,并完全支持所有相同的功能。这意味着你只需学习一次 Payload 的查询语言,就可以在所有可能用到的 API 中使用它。
要查询你的文档,你可以通过请求发送任意数量的 操作符:
import type { Where } from 'payload'
const query: Where = {
color: {
equals: 'blue',
},
}
具体的查询语法取决于你使用的 API,但所有 API 的概念都是相同的。更多详情。
提示: 你也可以在 访问控制 函数中使用查询。
操作符
以下操作符可用于查询中:
Operator | 描述 |
---|---|
equals | 值必须完全相等。 |
not_equals | 查询将返回所有值不相等的文档。 |
greater_than | 适用于数字或日期字段。 |
greater_than_equal | 适用于数字或日期字段。 |
less_than | 适用于数字或日期字段。 |
less_than_equal | 适用于数字或日期字段。 |
like | 不区分大小写的字符串必须存在。如果是多个单词组成的字符串,所有单词都必须存在,顺序不限。 |
contains | 必须包含输入的值,不区分大小写。 |
in | 值必须在提供的逗号分隔的值列表中找到。 |
not_in | 值必须不在提供的逗号分隔的值列表中。 |
all | 值必须包含逗号分隔列表中提供的所有值。注意:目前此操作符仅支持 MongoDB 适配器。 |
exists | 仅返回值存在(true )或不存在的文档(false )。 |
near | 用于与 Point Field 相关的距离查询,格式为逗号分隔的 <经度>, <纬度>, <最大距离(米,可选)>, <最小距离(米,可选)> 。 |
within | 用于 Point Fields,根据点是否位于 GeoJSON 定义的给定区域内筛选文档。示例 |
intersects | 用于 Point Fields,根据点是否与 GeoJSON 定义的给定区域相交筛选文档。示例 |
提示: 如果你知道用户会频繁查询某些字段,可以在 Field Config 中添加
index: true
。这将极大提高使用该字段的搜索速度。
与/或逻辑
除了定义简单查询外,你还可以使用 AND/OR 逻辑将多个查询组合起来。这些逻辑可以任意深度嵌套,以创建复杂的查询条件。
要组合查询,可以在查询对象中使用 and
或 or
键:
import type { Where } from 'payload'
const query: Where = {
or: [
// highlight-line
{
color: {
equals: 'mint',
},
},
{
and: [
// highlight-line
{
color: {
equals: 'white',
},
},
{
featured: {
equals: false,
},
},
],
},
],
}
用通俗语言描述,如果上述查询被传递给 find
操作,它将转换为查找满足以下条件的文章:color
等于 mint
,或者 color
等于 white
且 featured
设置为 false。
嵌套属性
当处理嵌套属性时(这在关系型字段中很常见),可以使用点符号访问嵌套属性。例如,当处理一个 Song
集合时,该集合有一个 artists
字段,该字段通过 name: 'artists'
关联到 Artists
集合。你可以像这样访问 Artists
集合中的属性:
import type { Where } from 'payload'
const query: Where = {
'artists.featured': {
// 要过滤的嵌套属性名
exists: true, // 使用的操作符及需要为真的布尔值
},
}
编写查询
在 Payload 中编写查询非常简单,所有 API 的语法都保持一致,只有细微的语法差异。
本地 API
Local API 支持接受原始查询对象的 find
操作:
import type { Payload } from 'payload'
const getPosts = async (payload: Payload) => {
const posts = await payload.find({
collection: 'posts',
where: {
color: {
equals: 'mint',
},
},
})
return posts
}
GraphQL API
在 GraphQL API 中,所有 find
查询都支持 where
参数,该参数接受原始查询对象:
query {
Posts(where: { color: { equals: mint } }) {
docs {
color
}
totalDocs
}
}
REST API
通过 REST API,你可以充分利用 Payload 的查询功能,但查询需要以查询字符串的形式编写:
https://localhost:3000/api/posts?where[color][equals]=mint
要理解这种语法,需要知道复杂的 URL 搜索字符串会被解析为 JSON 对象。这个例子还算简单,但更复杂的查询会不可避免地变得更难编写。
因此,我们推荐使用非常实用且广泛使用的 qs-esm
包,将你的 JSON/对象格式查询解析为查询字符串:
import { stringify } from 'qs-esm'
import type { Where } from 'payload'
const query: Where = {
color: {
equals: 'mint',
},
// 这个查询可以复杂得多
// qs-esm 都能完美处理
}
const getPosts = async () => {
const stringifiedQuery = stringify(
{
where: query, // 确保 `qs-esm` 也添加了 `where` 属性!
},
{ addQueryPrefix: true },
)
const response = await fetch(
`http://localhost:3000/api/posts${stringifiedQuery}`,
)
// 继续处理响应...
}