我有这样的查询:
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
过滤器的任何部分_is_null
和_or
一样使用Hasura boolExp
s,但似乎它们不能直接测试变量,它们只能将变量与列内容进行比较答案 0 :(得分:3)
您可以使用 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: {} }
答案 1 :(得分:2)
此行为在 v1.3.4 之间发生了变化。因此有两个正确答案。
您可以在 hasura repository 中阅读有关此更改的更多信息。
This answer 描述了它。
默认为 null
时在比较中使用 true
是危险的,因为意外未设置的变量可能会导致删除表。维护者删除了此行为,但通过设置变量 HASURA_GRAPHQL_V1_BOOLEAN_NULL_COLLAPSE
使其可访问。
当与 {_eq: null}
比较时,Hasura 会抛出一个错误,因为它假定这是一个错误。
如果您想与某个值进行比较并在值为 true
时计算为 null
,您需要在客户端站点上处理这种情况并将整个布尔表达式传递给 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。
答案 2 :(得分:0)
如果使用_eq
boolExp,则默认情况下,如果变量为null,则全部匹配似乎是默认行为。我没有看到此消息,因为此查询使用的是use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
class MappingNameConverter implements NameConverterInterface {
public function __construct(array $mapping) {
$this->mapping = $mapping;
}
public function denormalize($propertyName)
{
return $this->mapping[$propertyName];
}
}
。
如果$ setId作为use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
$mapping = ['full name' => 'name', 'aged' => 'age', ...];
$nameConverter = new MappingNameConverter($mapping);
$normalizer = new ObjectNormalizer(null, $nameConverter);
$serializer = new Serializer([$normalizer], [new CsvEncoder()]);
传递,则更改为所有项:
_in
这是因为Hasura遵循SQL,使null
不具有任何可比性(只有query getUsers ($setId: Int) {
user(where: { user_sets: { set_id: { _eq: $setId } } }) {
id
name
status
user_sets {
set {
name
}
}
# more fields...
}
}
可以匹配在可为空的列中设置为null的值)。
因此,null
在逻辑上无法匹配任何内容,因此已对其进行了优化。这个:
_is_null
...成为这个:
{ _eq: null }
...并且由于(where: { user_sets: { set_id: { _eq: $setId } } })
是trueExp
(被视为true),因此它可以有效地进行优化(where: { user_sets: { set_id: {} } }
。