REST API:过滤器
页面摘要: REST API 的过滤(filters)功能可使用
$eq、$contains、$between等运算符对查询结果进行过滤,支持使用$and、$or、$not进行复杂过滤,以及跨关联内容的深层过滤(deep filtering)。
REST API 提供了对通过 "Get entries" 方法获取的结果进行过滤的能力。
使用 Strapi 的可选功能可提供更多的过滤器:
- 若在某个 content-type 上启用了 国际化(i18n)插件,则可以按区域(locale)进行过滤。
- 若启用了 草稿与发布,则可以根据
published(默认)或draft状态进行过滤。
查询可以接受一个 filters 参数,语法如下:
GET /api/:pluralApiId?filters[field][operator]=value
可用的运算符如下:
| 运算符 | 说明 |
|---|---|
$eq | 等于 |
$eqi | 等于(不区分大小写) |
$ne | 不等于 |
$nei | 不等于(不区分大小写) |
$lt | 小于 |
$lte | 小于或等于 |
$gt | 大于 |
$gte | 大于或等于 |
$in | 包含在数组中 |
$notIn | 不包含在数组中 |
$contains | 包含 |
$notContains | 不包含 |
$containsi | 包含(不区分大小写) |
$notContainsi | 不包含(不区分大小写) |
$null | 为 null |
$notNull | 不为 null |
$between | 介于…之间 |
$startsWith | 以…开头 |
$startsWithi | 以…开头(不区分大小写) |
$endsWith | 以…结尾 |
$endsWithi | 以…结尾(不区分大小写) |
$or | 以「或」表达式连接过滤器 |
$and | 以「与」表达式连接过滤器 |
$not | 以「非」表达式连接过滤器 |
当在 filters 对象中传入多个字段时,它们会隐式地使用 $and 连接(例如 GET /api/restaurants?filters[stars][$gte]=3&filters[open][$eq]=true 仅返回营业中且至少有 3 颗星的餐馆)。
$and、$or 与 $not 运算符可以相互嵌套。
默认情况下,过滤器只能用于由 Content-type Builder 与 CLI 生成的 find 接口(endpoints)。
示例:查找名字为 'John' 的用户
使用 $eq 过滤运算符进行精确匹配。
cURL
curl 'http://localhost:1337/api/users?filters[username][$eq]=John' \
-H 'Authorization: Bearer <token>'
JavaScript
const qs = require('qs');
const query = qs.stringify({
filters: {
username: {
$eq: 'John',
},
},
}, {
encodeValuesOnly: true, // 美化 URL
});
await request(`/api/users?${query}`);
响应
{
"data": [
{
"id": 1,
"documentId": "znrlzntu9ei5onjvwfaalu2v",
"username": "John",
"email": "john@test.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"createdAt": "2021-12-03T20:08:17.740Z",
"updatedAt": "2021-12-03T20:08:17.740Z"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
示例:查找 id 为 3、6、8 的多家餐馆
使用 $in 过滤运算符配合值数组,查找多个精确值。
cURL
curl 'http://localhost:1337/api/restaurants?filters[id][$in][0]=3&filters[id][$in][1]=6&filters[id][$in][2]=8' \
-H 'Authorization: Bearer <token>'
JavaScript
const qs = require('qs');
const query = qs.stringify({
filters: {
id: {
$in: [3, 6, 8],
},
},
}, {
encodeValuesOnly: true, // 美化 URL
});
await request(`/api/restaurants?${query}`);
响应
{
"data": [
{
"id": 3,
"documentId": "ethwxjxtvuxl89jq720e38uk",
"name": "test3"
},
{
"id": 6,
"documentId": "ethwxjxtvuxl89jq720e38uk",
"name": "test6"
},
{
"id": 8,
"documentId": "cf07g1dbusqr8mzmlbqvlegx",
"name": "test8"
}
],
"meta": {}
}
复杂过滤(Complex filtering)
组合 $and 与 $or 运算符进行复杂过滤。
cURL
curl 'http://localhost:1337/api/books?filters[$and][0][$or][0][date][$eq]=2020-01-01&filters[$and][0][$or][1][date][$eq]=2020-01-02&filters[$and][1][author][name][$eq]=Kai%20doe' \
-H 'Authorization: Bearer <token>'
JavaScript
const qs = require('qs');
const query = qs.stringify({
filters: {
$and: [
{
$or: [
{
date: {
$eq: '2020-01-01',
},
},
{
date: {
$eq: '2020-01-02',
},
},
],
},
{
author: {
name: {
$eq: 'Kai doe',
},
},
},
],
},
}, {
encodeValuesOnly: true, // 美化 URL
});
await request(`/api/books?${query}`);
响应
{
"data": [
{
"id": 1,
"documentId": "rxngxzclq0zdaqtvz67hj38d",
"name": "test1",
"date": "2020-01-01"
},
{
"id": 2,
"documentId": "kjkhff4e269a50b4vi16stst",
"name": "test2",
"date": "2020-01-02"
}
],
"meta": {}
}
上面的响应只包含图书自身的属性。除非通过 populate 参数 显式请求(例如在请求中加上 &populate=author),否则由 $and 过滤器所遍历的 author 关联不会被返回。
深层过滤(Deep filtering)
- 关联、媒体字段、组件与动态区域默认不会被联表加载(populate)。使用
populate参数来加载这些内容结构(参见populate文档) - 你可以过滤所联表加载的内容,也可以过滤嵌套关联,但无法对多态内容结构(如媒体字段与动态区域)使用过滤器。
使用深层过滤器查询 API 可能会导致性能问题。如果你的某个深层过滤查询过慢,建议构建一个自定义路由(custom route)并采用优化后的查询版本。
如需各类 API 深度过滤的示例,请参阅这篇博客文章。
使用深层过滤对关联字段进行过滤。
cURL
curl 'http://localhost:1337/api/restaurants?filters[chef][restaurants][stars][$eq]=5' \
-H 'Authorization: Bearer <token>'
JavaScript
const qs = require('qs');
const query = qs.stringify({
filters: {
chef: {
restaurants: {
stars: {
$eq: 5,
},
},
},
},
}, {
encodeValuesOnly: true, // 美化 URL
});
await request(`/api/restaurants?${query}`);
响应
{
"data": [
{
"id": 1,
"documentId": "cvsz61qg33rtyv1qljb1nrtg",
"name": "GORDON RAMSAY STEAK",
"stars": 5
},
{
"id": 2,
"documentId": "uh17h7ibw0g8thit6ivi71d8",
"name": "GORDON RAMSAY BURGER",
"stars": 5
}
],
"meta": {}
}
上面的响应与默认的 REST 输出一致,不包含过滤器所遍历的关联。添加 populate 参数,例如 &populate[chef][populate][restaurants]=true,以同时返回过滤器中引用的 chef.restaurants 关联。