Как получить только самые свежие из всех документов

В sanity studio вы получаете хороший список самых последних версий всех ваших документов. Если есть черновик, вы его получите, если нет, вы получите опубликованный.

Мне нужен тот же список для нескольких фильтров и скриптов. Следующий groq выполняет свою работу, но не очень быстро и не работает в новом API (v2021-03-25).

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

Чтобы обойти критические изменения в API, используйте length() = 0 на месте !defined() но это делает и без того медленный запрос в 10-20 раз медленнее.

Кто-нибудь знает способ сделать фильтры, учитывающие только последнюю версию?

Изменить: пример, когда мне это нужно, - это если я хочу видеть все документы без каких-либо категорий. Независимо от того, опубликован ли это документ или черновик без категорий, он отображается в обычном фильтре. Поэтому, если вы добавляете категории, но не хотите сразу публиковать, это будет сбивать с толку в списке без категорий. ,'-)

2 ответа

100-кратное улучшение API v2021-03-25 🥳

Единственный способ, которым я смог решить эту проблему быстро, - это сначала сделать проекцию подзапроса, чтобы он не запускался один раз для каждого не-черновика. Он выглядит полностью раздутым, но работает более чем в 10 раз быстрее, чем возможно на API v1, и в 100 раз быстрее, чем любые предложения по новому API.

      {
  // First I do the subquery and "store" it for in a projection (variable-😉-ish)
  'drafts': *[ 
    _type == $type && 
    _id in path("drafts.**")
  ]._id
}
{
  // Then I get all non-drafts.
  'current': *[ 
    _type == $type && 
    !(_id in path("drafts.**")) &&
    // 👇 And filter out any that has a counterpart in my "drafts-variable"
    !("drafts." + _id in ^.drafts) ]._id
  + drafts
  // Lastly I add the add all drafts to the my list of filtered non-drafts.
}

В целом, я думаю, вы на правильном пути. Некоторые идеи, которые могут вам помочь:

  1. Черновики всегда свежее и новее, чем опубликованные документы, поэтому, если id in path("drafts.**"), это уже последний обновленный.
  2. Знание вышеизложенного позволяет пропустить defined(*[_id == ...]) часть запроса для черновиков, ускоряющая выполнение
  3. Поскольку черновики уже включены, мы можем исключить опубликованные документы с черновиком ( defined(*[_id == "drafts." + ^._id][0]))
  4. Обратите внимание, я добавил [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

Надеюсь, это поможет 🙌

Другие вопросы по тегам