如何获取所有文档中的最新文档

How to get just the most recent of all documents

在 sanity studio 中,您可以获得所有文档的最新版本的精美列表。如果有草稿,您会得到它,如果没有,您会得到已发布的草稿。

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

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

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

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

Edit: An example where I need this is if I want to see all documents without any categories. Regardless whether it is the published document or the draft that has no categories it shows up in a normal filter. So if you add categories but don't immediately want to publish it will be confusing in the no-categories-list. ,'-)

总体而言,我认为您的方向是正确的。一些可以帮助您的想法:

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

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

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