1

在 sanity studio 中,您会获得一份包含所有文档的最新版本的漂亮列表。如果有草稿,你会得到它,如果没有,你会得到出版的。

对于一些过滤器和脚本,我需要相同的列表。以下 groq 完成了这项工作,但速度不是很快,并且在新 API (v2021-03-25) 中不起作用。

*[
  _type == $type &&
  !defined(*[_id == "drafts." + ^._id])
]._id

绕过 API 中的重大更改的一种方法是使用length() = 0代替,!defined()但这会使已经很慢的查询慢 10-20 倍。

有谁知道制作只考虑最新版本的过滤器的方法?

编辑:我需要这个的一个例子是,如果我想查看没有任何类别的所有文档。无论是已发布文档还是没有类别的草稿,它都会显示在普通过滤器中。因此,如果您添加类别但不想立即发布它会在 no-categories-list 中造成混淆。,'-)

4

2 回答 2

2

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
}
  1. 首先,我得到草稿和非草稿,并将其“存储”在这个投影中,就像一个变量——ish
  2. 然后我从我的非草稿开始——published
  3. drafts并过滤掉任何在我的“变量”中具有对应项的内容
  4. 最后,我将所有草稿添加到我的过滤非草稿列表中
于 2021-04-06T16:47:05.007 回答
1

总的来说,我认为你在正确的轨道上。一些可以帮助您的想法:

  1. 草稿总是比已发布的文档更新和更新,因此如果给定文档id in path("drafts.**"),那已经是最后更新的文档了。
  2. 了解以上内容可以让您跳过defined(*[_id == ...])草稿查询的部分,加快您的执行速度
  3. 由于已经包含草稿,我们可以排除带有草稿 ( defined(*[_id == "drafts." + ^._id][0]))的已发布文档
  4. 请注意,我在查询末尾添加了 a[0]以仅选择匹配的第一个元素。这将略微提高性能。
  5. 要仅获取没有类别的文档,请使用count(categoriesField) < 1
  6. 订购文件以| order(_updatedAt desc)首先获得最新的文件
  7. 并对您的请求进行分页以减少有效负载并加快速度。

这是一个应用这些原则的示例查询(我没有运行它,您可能需要在那里进行一些调整):

*[
  _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

希望这可以帮助

于 2021-04-02T11:44:05.057 回答