仅当变量不为空时,如何应用 Hasura `where` 过滤器?
Posted
技术标签:
【中文标题】仅当变量不为空时,如何应用 Hasura `where` 过滤器?【英文标题】:How to apply a Hasura `where` filter only if a variable is not null? 【发布时间】:2019-09-12 13:16:34 【问题描述】:我有一个这样的查询:
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] ' : '' )
`
我尝试过的一些事情:
像@skip
和@include
一样使用GraphQL directives,但似乎这些仅适用于返回的字段,不适用于where
过滤器的任何部分
使用Hasura boolExp
s 像_is_null
和_or
,但似乎这些不能直接测试变量,它们只能将变量与列内容进行比较
【问题讨论】:
【参考方案1】:如果使用了_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 的值)。
因此, _eq: null
在逻辑上无法匹配任何内容,因此它只是被优化掉了。这个:
(where: user_sets: set_id: _eq: $setId )
...变成这样:
(where: user_sets: set_id:
...因为 是
trueExp
,被视为真,它优化为有效WHERE 'true'
。
【讨论】:
对于gte
、lte
和in
的空数组等其他选项是否有解决方案?
这在 v2.0 中有所改变。发布说明中的更多内容,行为更改部分:github.com/hasura/graphql-engine/releases/tag/v2.0.0-alpha.1
@Friedrich 如果你能写出最新的 v2.0 答案,那就太好了
@Friedrich 我想更多的是您将其发布为您自己的答案,我会接受它(我也可能会在我的评论中编辑一条评论,说我的适用于 v1.x 并链接到你作为 v2.x 的答案)。这样你就可以得到它的功劳,你就能更好地保持更新或响应 cmets(我不再与 Hasura 合作,所以我不能这样做)。此外,SO 通常不喜欢这样的 3rd 方编辑的大变化。
好的,我会这样做的。【参考方案2】:
在这种情况下,您可以使用 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:
【讨论】:
【参考方案3】:这种行为在 v1.3.4 之间发生了变化。因此有两个正确答案。
您可以在hasura repository 中阅读有关此更改的更多信息。
1.3.4版本之前
This answer 描述了它。
1.3.4 之后
在默认为true
时在比较中使用null
是危险的,因为意外取消设置的变量可能会导致表被删除。维护者删除了这种行为,但通过设置变量 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。
【讨论】:
这应该是最佳答案,因为 Hasura 现在是 v2。以上是关于仅当变量不为空时,如何应用 Hasura `where` 过滤器?的主要内容,如果未能解决你的问题,请参考以下文章