仅当变量不为空时,如何应用 Hasura `where` 过滤器?

How to apply a Hasura `where` filter only if a variable is not null?

我有这样的查询:

query getUsers ($setId: Int) {
  user(where: { user_sets: { set_id: { _in: [$setId] } } }) {
    id
    name
    status
    user_sets {
      set {
        name
      }
    }
    # more fields...
  }
}

我正在寻找的是一种不应用 where 过滤器并在 $setId 为空时提供所有条目的方法。我想避免动态编写查询 - 这样做很容易,但我们希望在静态 .graphql 文件中查询:

const query = `
query getUsers (${ setId ? '$setId: Int' : ''}) {
  user(${ setId ? 'where: { user_sets: { set_id: { _in: [$setId] } } }' : '' }) {
`

我尝试过的一些事情:

如果使用 _eq boolExp,那么如果变量为空则匹配所有似乎是默认行为。我没有看到这个,因为这个查询使用的是 _in.

如果将 $setId 作为 null:

传递,则更改为此会提供所有项目
query getUsers ($setId: Int) {
  user(where: { user_sets: { set_id: { _eq: $setId } } }) {
    id
    name
    status
    user_sets {
      set {
        name
      }
    }
    # more fields...
  }
}

这是因为 Hasura 遵循 SQL,使 null 无法与任何东西进行比较(只有 _is_null 可以匹配在可为 null 的列中设置为 null 的值)。

因此,{ _eq: null }逻辑上不能匹配任何东西,所以它被简单地优化掉了。这个:

(where: { user_sets: { set_id: { _eq: $setId } } })

...变成这样:

(where: { user_sets: { set_id: {} } }

...并且因为 {}trueExp,被视为 true,它优化为有效 WHERE 'true'.

对于这种情况,您可以使用 bool 表达式作为绑定变量

query getUsers ($condition: user_bool_exp!) {
  user (where: $condition) {
    id
    name
    status
    user_sets {
      set {
        name
      }
    }
    # more fields...
  }
}

并且您可以根据变量构建条件

{ condition: { user_sets: { set_id: { _in: [$setId] } } } }

{ condition: { user_sets: {} }

此行为在 v1.3.4 之间的某处发生了变化。因此有两个正确答案。

您可以在 hasura repository.

中阅读有关此更改的更多信息

版本 1.3.4 之前

描述了它。

版本 1.3.4 之后

在默认为 true 时,在比较中使用 null 是危险的,因为意外取消设置的变量可能会导致 table 丢失。维护者删除了此行为,但通过设置变量 HASURA_GRAPHQL_V1_BOOLEAN_NULL_COLLAPSE.

使其可访问

{_eq: null} 比较时,Hasura 会抛出错误,因为假定这是一个错误。

如果您想比较一个值并在值为 null 时求值为 true,您需要在客户端处理这种情况并将整个布尔表达式传递给 hasura。

query getUsers ($userSetsWhere: user_sets_bool_exp) {
  user(where: { user_sets: { $userSetsWhere } }) {
    id
    name
    status
    user_sets {
      set {
        name
      }
    }
    # more fields...
  }
}
const userSetsWhere = setId ? { set_id: { _eq: $setId } } : {};

什么是,只有在值不是 nullundefined 的情况下,才会将非空表达式传递给 hasura。