仅当变量不为空时,如何应用 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] } } }' : '' }) {
`
我尝试过的一些事情:
- 使用 GraphQL directives,如
@skip
和 @include
,但似乎这些仅适用于返回的字段,不适用于 where
过滤器的任何部分
- 像
_is_null
和_or
一样使用Hasura boolExp
s,但似乎这些不能直接测试变量,它们只能将变量与列内容进行比较
如果使用 _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 } } : {};
什么是,只有在值不是 null
或 undefined
的情况下,才会将非空表达式传递给 hasura。
我有这样的查询:
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] } } }' : '' }) {
`
我尝试过的一些事情:
- 使用 GraphQL directives,如
@skip
和@include
,但似乎这些仅适用于返回的字段,不适用于where
过滤器的任何部分 - 像
_is_null
和_or
一样使用HasuraboolExp
s,但似乎这些不能直接测试变量,它们只能将变量与列内容进行比较
如果使用 _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 } } : {};
什么是,只有在值不是 null
或 undefined
的情况下,才会将非空表达式传递给 hasura。