You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sanity GROQ如何获取文档中引用数组的关联草稿数据?

问题背景

定义了page类型文档,文档包含blocks数组,数组项为指向其他对象类型的引用。拉取page文档数据时,文档本身的草稿数据可正常返回,但数组内引用关联的草稿数据无法正常获取。

当前使用的可同时返回文档草稿与已发布数据的GROQ查询如下:

*[_type == "page" && slug.current == "${querySlug === '/' ? 'home' : querySlug}"] {
  _id,
  title,
  description,
  showSubNav,
  subNavigation[] -> {slug, title},
  blocks[] -> {
    ...,
    heroCardBlock -> {...},
    oneColumnContent -> {...},
    featuredNews -> {...},
    newsCategories[] -> {...},
    newsList[] -> {..., selectedCategory -> {...}},
    caseStudiesListSource[] -> {...},
  }
}

执行上述查询时,page文档的草稿、已发布版本均可正常返回,title、description、showSubNav等非引用字段的草稿数据可正常获取,但subNavigation、blocks这类存储引用的数组字段仅返回已发布数据,无法返回对应引用的草稿内容。

问题原因

GROQ默认的->引用解析逻辑,只会匹配_id不带drafts.前缀的已发布文档,不会自动关联引用对象的草稿版本。哪怕父文档查询到了草稿版本,其内部存储的引用字段默认记录的还是已发布文档的ID,不会自动指向草稿,因此默认解析拿不到引用的草稿数据。

解决方案

替换所有层级默认的->解析逻辑,解析引用时同时匹配「原引用ID对应的已发布文档」和「加drafts.前缀的草稿文档」,通过ID倒序排序优先取草稿,草稿不存在时自动回退到已发布版本。
调整后的完整查询如下:

*[_type == "page" && slug.current == "${querySlug === '/' ? 'home' : querySlug}"] {
  _id,
  title,
  description,
  showSubNav,
  // 重写subNavigation引用解析,优先取草稿
  "subNavigation": subNavigation[] {
    "_key": _key,
    "data": *[_id in [@->_ref, "drafts." + @->_ref]] | order(_id desc)[0] {
      slug,
      title
    }
  },
  // 重写blocks数组引用解析
  "blocks": blocks[] {
    "_key": _key,
    "_type": _type,
    "data": *[_id in [@->_ref, "drafts." + @->_ref]] | order(_id desc)[0] {
      ...,
      // 处理block内部的单引用字段
      "heroCardBlock": heroCardBlock != null => *[_id in [^.heroCardBlock._ref, "drafts." + ^.heroCardBlock._ref]] | order(_id desc)[0] {...},
      "oneColumnContent": oneColumnContent != null => *[_id in [^.oneColumnContent._ref, "drafts." + ^.oneColumnContent._ref]] | order(_id desc)[0] {...},
      "featuredNews": featuredNews != null => *[_id in [^.featuredNews._ref, "drafts." + ^.featuredNews._ref]] | order(_id desc)[0] {...},
      // 处理block内部的数组引用字段
      "newsCategories": newsCategories[] {
        "_key": _key,
        "data": *[_id in [@->_ref, "drafts." + @->_ref]] | order(_id desc)[0] {...}
      },
      "newsList": newsList[] {
        "_key": _key,
        "data": *[_id in [@->_ref, "drafts." + @->_ref]] | order(_id desc)[0] {
          ...,
          // 处理嵌套的二级引用
          "selectedCategory": selectedCategory != null => *[_id in [^.selectedCategory._ref, "drafts." + ^.selectedCategory._ref]] | order(_id desc)[0] {...}
        }
      },
      "caseStudiesListSource": caseStudiesListSource[] {
        "_key": _key,
        "data": *[_id in [@->_ref, "drafts." + @->_ref]] | order(_id desc)[0] {...}
      }
    }
  }
}

注意事项

  • 排序逻辑利用了字符串排序规则:带drafts.前缀的ID比普通ID长,倒序排列时会排在最前面,因此取排序后的第一条即可优先获得草稿版本,草稿不存在时自动返回已发布版本。
  • 如果项目自定义了草稿前缀(不是默认的drafts.),需要把查询中所有前缀字符串替换为项目实际配置值。
  • 所有嵌套层级的引用都要使用上述逻辑重写解析,不能直接用默认->,否则对应层级依然只会返回已发布数据。

内容的提问来源于stack exchange,提问作者Mutahhar Ahmad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:12:35