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

如何在Sanity.io中按指定slug筛选查询单条匹配数据

Sanity GROQ按slug筛选单条文档实现方案

问题场景

现有如下游戏数据集:

[
  {
    "name": "Gates of Olympus",
    "slug": {
      "_type": "slug",
      "current": "gates-of-olympus"
    }
  },
  {
    "name": "Floating Dragon",
    "slug": {
      "_type": "slug",
      "current": "floating-dragon"
    }
  },
  {
    "name": "Buffalo King Megaways",
    "slug": {
      "_type": "slug",
      "current": "buffalo-king-megaways"
    }
  },
  {
    "name": "Fruit Party",
    "slug": {
      "_type": "slug",
      "current": "fruit-party"
    }
  }
]

需求为仅查询slug.current等于目标值的对象,目标slug从路由上下文获取,对应变量为params.game。
当前未加筛选的初始代码会返回全量游戏数据,代码如下:

export const getServerSideProps = async ({params}:any) => {
    
    const query = `*[_type=="game"]{
    name,
    slug,
    }`;
  
    const games = await sanityClient.fetch(query);
  
    return {
      props: {
        games,
      },
    };
  };

此前尝试直接用模板字符串拼接筛选条件的写法失效,执行后仍返回全量数据,错误写法如下:

*[_type=="game" && slug.current == ${params.game}]

失效原因

直接在GROQ语句中用模板字符串拼接动态值存在两个核心问题:

  • 字符串类型的值没有手动包裹引号,会导致查询条件解析异常,筛选逻辑直接不生效
  • 直接拼接参数存在查询注入风险,参数中包含特殊字符时会直接破坏查询语法

正确实现

使用Sanity官方推荐的参数化查询方式,动态值通过fetch方法的第二个参数传入,不需要手动拼接字符串,修正后的完整代码如下:

export const getServerSideProps = async ({params}) => {
    // GROQ语句中用$前缀声明参数,单条查询末尾加[0]直接取匹配结果的第一项
    const query = `*[_type=="game" && slug.current == $targetSlug][0]{
      name,
      slug
    }`;
  
    // 传入查询对应的参数,客户端会自动处理类型转义
    const game = await sanityClient.fetch(query, {
      targetSlug: params.game
    });

    // 无匹配数据时返回404状态
    if (!game) {
      return { notFound: true }
    }
  
    return {
      props: {
        game,
      },
    };
};

关键说明

  • 所有动态查询参数统一通过$参数名占位,Sanity客户端会自动根据参数类型处理格式,字符串值不需要手动加引号
  • 查询条件后加[0]是因为GROQ的筛选结果默认返回数组,单条文档查询直接取第一个元素即可,无需额外遍历数组取值
  • 原查询语句中slug字段后多余的尾逗号已移除,避免低版本解析器抛出语法错误
  • 增加空值判断逻辑,匹配不到对应slug的文档时直接返回404状态,符合Next.js路由处理规范

内容的提问来源于stack exchange,提问作者Sai Krishnadas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:57:23