如何仅查询这些对象,这些对象包含使用 Hasura 作为变量给出的数组中的每个元素?

Posted

技术标签:

【中文标题】如何仅查询这些对象,这些对象包含使用 Hasura 作为变量给出的数组中的每个元素?【英文标题】:How to query only these object containing each element from the array given as a variable using Hasura? 【发布时间】:2020-08-19 07:05:51 【问题描述】:

我的数据库中有一个“学生”表(使用 Hasura 的 postgress),与“主题”的关系是多对多的:

type Student = 
    id: uuid
    name: String
    subjects: [subject]


type Subject = 
    id: uuid
    name: String

我有一个静态QUERY1

query FilteredStudents($subjects: [String!]) 
    students(where:  subjects:  name:  _in: $subjects   ) 
        id
        name
    

例如:

$subjects = ['Math', 'English', 'Physics']

它将找到参加任何这些课程的所有学生。 例如:

const student1 = 
   id: 1,
   name: 'Mike',
   subjects: ['Physics', 'Chemistry']  // subjects mapped to names for simplicity

我的问题是我想要另一个查询来查找参加这些课程中每个的所有学生。

所以它不应该获取 student1,而应该像这样获取学生:

const student2 = 
   id: 2,
   name: 'Walt',
   subjects: ['Math', 'English', 'Physics', 'Some', 'other', 'subjects']  // subjects mapped to names for simplicity

我唯一的想法是创建这样的动态查询:Dynamic QUERY2(每次 $subject 数组更改时都会生成一个新查询(在运行时) ):

query FilteredStudents 
    students(where:  _and: [
        subjects:  name:  _eq: "Math"  
        subjects:  name:  _eq: "English"   
        subjects:  name:  _eq: "Physics"   
    ]) 
        id
        name
    

但我真的很想避免这种情况并找到一些静态解决方案。有没有办法使用 Hasura 提供的过滤器来实现这一点? (https://hasura.io/docs/1.0/graphql/manual/queries/query-filters.html#)

【问题讨论】:

呃,这个我想不出来。我能想到的两个选项都不是很好。 1. 在Query 1 中获取所有像你一样的用户,然后在客户端过滤它们 2. 将所有关系添加到hasSubjects JSON 列,然后像这样过滤hasura.io/docs/1.0/graphql/manual/queries/… 【参考方案1】:

我可以将您的 QUERY2 命名为静态,将 QUERY1 命名为动态 - 第一个是参数化的,第二个是硬编码的。

您可以为两者构造和传递整个 where 对象作为变量。

您可以阅读this 并将_not_nin 一起使用(如'_and' 用法)。它仍然是动态条件,因为 where 是输入类型 ...并且条件对象创建复杂度几乎相同。

更新

const subset = ['Math', 'English'];

const condition =  _and: [] ;
subset.map( el => 
  condition._and.push( 
    subjects:  name:  _eq: el   
  );
);

callSomeLazyQuery(  variables: 
  where: condition 
 );

同样应该有效

const condition = 
  _not:  
    _and: [] 
  
;
subset.map( el => 
  condition._not._and.push( 
    subjects:  name:  _nil: el   
  );
);

【讨论】:

我将 QUERY1 称为静态,因为它是硬编码的 - 我只能操作传递给此查询的变量。 QUERY2 只是runtime 上生成的查询示例,因此每次$subject 数组更改时我都需要生成一个新查询——这就是我称它为动态的原因。关于_not_nin 的解决方案 - 已经尝试过了,但它 匹配具有我传递给它的完全相同科目的学生。对于$subjects=['Math', 'German'],它将返回仅具有这些科目的学生,但我也希望获得具有例如:["Math", "German", "Chemistry"] 的学生。 由谁硬编码?由谁产生?不应该生成查询 - 这是一种不好的做法(例如操作字符串以粘合 SQL 查询)...在服务器突变上,where 只需要一个参数,您的应用程序应该创建并作为变量传递这个参数 _not_nin 应该可以工作,也许 _not _and _nin? - 逐步测试,单独_nin ...如果您确定它应该工作准备证明minimal reproducible example 并提出问题? ....无论如何 - 你可以使用已经工作的_and _eq 硬编码 - 由我,由函数生成(在运行时)。是的,我认为这是一种不好的做法,这就是为什么我问是否有更好的解决方案。我想使用简单的where,但似乎没有简单的解决方案(或者我找不到)。我刚刚向您展示了为什么 _not_nin 不起作用。猜测_not _and _nin 的哪个组合可能有效是一种糟糕的方法。 “你可以使用已经工作的 _and _eq” - 这是一个非常大胆的假设,你知道这样的查询会是什么样子吗?因为我什么都没想到。 查看更新的答案...在重建过程中可以逐步分解和检查逻辑组合(您可以检查单个_nin,两个_nin与_and以及单个_nin的否定等),这并不可怕; )

以上是关于如何仅查询这些对象,这些对象包含使用 Hasura 作为变量给出的数组中的每个元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何仅从 JSON 文件导入不和谐?

如何检查对象数组中这些对象中的特定属性?反应

您将如何使用 Spring Boot 处理仅具有可选查询参数的 REST API?

Android单元测试:如何模拟包含MutableLiveData但仅公开LiveData的对象?

嵌套对象的 Hasura GraphQL UPSERT 突变

使用 jQuery 动态创建对象