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

GraphQL带where子句动态查询 如何处理可选过滤参数

问题原因

你当前的写法存在两个核心问题:

  • 传""跳过过滤的逻辑是错误的:你在where条件中固定写了三个_eq等值匹配规则,当传入空字符串时,数据库会执行slug = ""的匹配逻辑,你的库中没有对应slug为空的记录,自然返回空结果。
  • 现有的查询没有做可选过滤的兼容,所有条件都是强制生效的,不管参数值是什么都会参与查询判断。

解决方案

这里提供三种适配可选过滤的实现方式,你可以根据自己的使用场景选择:

方案1:Hasura原生条件逻辑(依赖Hasura GraphQL引擎)

你使用的查询语法是Hasura的标准语法,可以直接在where中增加参数非空判断逻辑,实现参数为null时自动跳过过滤:

query getJobsSearch($location: String = null, $type: String = null, $category: String = null) {
  jobs(
    order_by: {created_at: desc}, 
    where: {
      deleted_at: {_is_null: true}, 
      created_at: {_gt: "2021-06-16T10:06:38.551984+00:00"},
      _and: [
        { _or: [ { $location: { _is_null: true } }, { location: { slug: { _eq: $location } } } ] },
        { _or: [ { $category: { _is_null: true } }, { job_category: { slug: { _eq: $category } } } ] },
        { _or: [ { $type: { _is_null: true } }, { job_type: { slug: { _eq: $type } } } ] }
      ]
    }, 
    limit: 50
  ) {
    jobId
    title
    company_name
    job_category {
      name
      slug
    }
    job_type {
      name
      slug
    }
    isRemote
    location {
      city
      slug
    }
    created_at
  }
}

传参规则:

  • 查全量数据:直接传{"location": null, "type": null, "category": null}或者空对象{}即可
  • 单条件过滤:比如只按location查询,传{"location": "new-delhi"},另外两个参数不传默认是null,自动跳过对应过滤

方案2:通用GraphQL @skip指令(不依赖后端实现)

用GraphQL原生的@skip指令控制是否加载对应过滤条件,兼容性更强:

query getJobsSearch(
  $location: String = null, 
  $type: String = null, 
  $category: String = null,
  $skipLocation: Boolean! = true,
  $skipCategory: Boolean! = true,
  $skipType: Boolean! = true
) {
  jobs(
    order_by: {created_at: desc}, 
    where: {
      deleted_at: {_is_null: true}, 
      created_at: {_gt: "2021-06-16T10:06:38.551984+00:00"},
      location: {slug: {_eq: $location}} @skip(if: $skipLocation),
      job_category: {slug: {_eq: $category}} @skip(if: $skipCategory),
      job_type: {slug: {_eq: $type}} @skip(if: $skipType)
    }, 
    limit: 50
  ) {
    # 原有返回字段不变
  }
}

传参规则:

  • 查全量数据:不需要传任何参数,三个skip默认都是true,自动跳过所有过滤
  • 单条件过滤:比如只按location查询,传{"location": "new-delhi", "skipLocation": false}即可

方案3:业务代码动态拼接条件(最接近Ruby链式查询的写法)

你可以在业务代码中像Ruby链式查询一样,有值的时候才拼接对应过滤条件,最后把整个where作为变量传给GraphQL:

// 示例:JS代码中的逻辑
const baseWhere = {
  deleted_at: {_is_null: true},
  created_at: {_gt: "2021-06-16T10:06:38.551984+00:00"}
}
// 有值才追加条件,和Ruby链式查询逻辑一致
if (location) baseWhere.location = {slug: {_eq: location}}
if (category) baseWhere.job_category = {slug: {_eq: category}}
if (type) baseWhere.job_type = {slug: {_eq: type}}

// 执行查询时把baseWhere作为where变量传入即可

对应的查询语句可以简化为:

query getJobsSearch($where: jobs_bool_exp!) {
  jobs(
    order_by: {created_at: desc}, 
    where: $where, 
    limit: 50
  ) {
    # 原有返回字段不变
  }
}

内容的提问来源于stack exchange,提问作者Harsha M V

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:45:01