问题描述
在 sanity studio 中,您可以获得所有文档的最新版本的不错列表。如果有草稿,你会得到,如果没有,你会得到已发布的。
我需要一些过滤器和脚本的相同列表。以下 groq 可以完成这项工作,但速度不是很快,并且在新 API (v2021-03-25) 中不起作用。
*[
_type == $type &&
!defined(*[_id == "drafts." + ^._id])
]._id
绕过 API 中的重大更改的一种方法是使用 length() = 0
代替 !defined()
,但这会使已经很慢的查询慢 10-20 倍。
有谁知道制作只考虑最新版本的过滤器的方法吗?
编辑:我需要这个的一个例子是,如果我想查看没有任何类别的所有文档。无论是已发布的文档还是没有类别的草稿,它都会显示在普通过滤器中。因此,如果您添加类别但不想立即发布,则会在 no-categories-list 中造成混淆。,'-)
解决方法
总的来说,我认为您走在正确的轨道上。一些想法可以帮助您:
- 草稿总是比已发布的文档更新,因此如果给定文档的
id in path("drafts.**")
,那已经是最后更新的文档。 - 了解上述内容后,您就可以跳过草稿查询的
defined(*[_id == ...])
部分,从而加快您的执行速度 - 由于草稿已包含在内,我们可以使用草稿 (
defined(*[_id == "drafts." + ^._id][0])
) 排除已发布的文档 - 注意我在查询的末尾添加了一个
[0]
以仅选择匹配的第一个元素。这将略微提高性能。 - 要仅获取没有类别的文档,请使用
count(categoriesField) < 1
- 使用
| order(_updatedAt desc)
订购文档以首先获取最新的文档 - 并对您的请求进行分页,以减少负载并加快处理速度。
以下是应用这些原则的示例查询(我没有运行过,您可能需要在那里进行一些调整):
*[
_type == $type &&
// Assuming you only want those without categories:
count(categories) < 1 &&
(
// Is either a draft -> drafts are always fresher
_id in path("drafts.**") ||
// Or a published document with no draft
!defined(*[_id == "drafts." + ^._id][0])
// ? with the check above we're ensuring only
// published documents run the expensive defined query
)
]
// Order by last updated
| order(_updatedAt desc)
// Paginate for faster queries
[$paginationStart..$paginationEnd]
// Get only the _id,assuming that's what you want
._id
希望对你有帮助?
,API v2021-03-25 100 倍改进?
我能够快速解决这个问题的唯一方法是首先对子查询进行投影,这样它就不会为每个非草稿运行一次。然后我想,为什么不投影两个集合然后找出重叠,那就更快了!它的运行速度比 API v1 上的速度快 10 倍以上,比新 API 的任何建议快 100 倍。
{
'drafts': *[ _type == $type && _id in path("drafts.**") ]._id,'published': *[ _type == $type && !(_id in path("drafts.**"))]._id,}
{
'current': published[ !("drafts." + @ in ^.drafts) ] + drafts
}
- 首先,我获得草稿和非草稿,并将其“存储”在此投影中,就像一个变量-?-ish
- 然后我从我的非草稿开始 -
published
- 并过滤掉在我的
drafts
“变量”中有对应项 - 最后,我将所有草稿添加到我的过滤非草稿列表中