GraphQL:过滤数组中的数据
GraphQL: Filter data in an array
我确信这是一件简单的事情,但我在 GraphQL 的文档或 Graphcool 的文档中找不到任何内容。
假设我有一个具有此模式的实体(GraphQL 新用户,如果我在模式表示中出错,抱歉):
Book {
name: String!
author: String!
categories: [String!]
}
如何查询属于 "mystery"
类别的所有图书?我知道我可以使用 allBooks(filter: {})
进行过滤,但是 categories_in: ["mystery"]
和 categories_contains: "mystery"
没有成功。
如果您有兴趣使用托管的 GraphQL 服务,scaphold.io 已经有一段时间了。 API 中的所有连接字段都带有一个 WhereArgs
参数,该参数公开过滤器,让您真正深入挖掘数据。当您有一个这样的标量列表时,WhereArgs 包含一个 contains
& notContains
字段,允许您根据列表中的值过滤结果。这允许您进行这样的查询。
query MysteriousBooks($where:BookWhereArgs) {
viewer {
allBooks(where:$where) {
edges { node { title, ... } }
}
}
}
# Variables
{
"where": {
"categories": {
"contains": "mystery"
}
}
}
为了完整起见,您还可以对架构进行轻微的重新调整,使这项工作无需在标量列表上进行过滤。例如,您可以使 Category
成为节点实现类型,然后在 Category
和 Book
之间创建连接。虽然 Book
可能不会有很多类别,但这将允许您发出这样的查询:
query MysteriousBooks($where: CategoryWhereArgs) {
viewer {
allCategories(where: $where) {
books {
edges { node { title, ... } }
}
}
}
}
# Variables
{
"where": {
"name": {
"eq": "mystery"
}
}
}
如果您以这种方式构建架构,那么您还可以对类别中的书籍进行更多过滤,而不必遍历档案中的每一本书。例如。你可以有效地要求 "all the mystery books written in the last year."
完全披露:我在 Scaphold 工作,尽管我希望您尝试一下,但如果您不转换,我不会感到难过。我很高兴看到人们尝试并热爱 GraphQL。如果您对如何在自己的服务器上实现此类行为感到好奇,请告诉我,我也很乐意为您提供帮助!
希望对您有所帮助!
Category
型号
考虑一下这种情况,创建一个 Category
模型绝对是可行的方法。
例如,假设您想允许读者稍后订阅他们喜欢的类别。或者,如果您想要所有现有类别的列表怎么办?使用字符串列表,您需要查询所有书籍并以某种方式对所有获得的类别进行后处理。在模型级别处理这个而不是使用字符串列表感觉更自然。
相反,您可以创建一个新的 Category
模型并在 Category
和 Book
之间添加多对多关系。在这种情况下,我喜欢添加一个唯一的枚举字段 tag
和一个字符串字段 text
。 (一个独特的字符串字段 tag
单独也是合适的,可能是个人喜好问题。)
使用此设置,您可以轻松满足
等数据要求
哪些书籍被分配到给定类别?
query {
# query books by unique category tag
Category(tag: MYSTERY) {
books {
id
}
}
# query books by specific category text
Category(filter: {
text: "mystery"
}) {
books {
id
}
}
}
哪些书籍至少被分配到给定列表的一个类别?
query {
allCategories(filter: {
OR: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
哪些书被分配到给定列表的所有类别?
query {
allCategories(filter: {
AND: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
相关过滤器
即使上述查询满足指定的数据要求,书籍在响应中按 Category
分组,这意味着我们必须在客户端上展平分组。
使用所谓的相关过滤器,我们可以将其转换为仅根据定义相关类别的条件获取书籍。
例如,要查询 分配给给定列表中至少一个类别的图书:
query {
allBooks(filter: {
OR: [{
categories_some: {
tag: MYSTERY
},
categories_some: {
tag: MAGIC
}
}]
}) {
id
}
}
我确信这是一件简单的事情,但我在 GraphQL 的文档或 Graphcool 的文档中找不到任何内容。
假设我有一个具有此模式的实体(GraphQL 新用户,如果我在模式表示中出错,抱歉):
Book {
name: String!
author: String!
categories: [String!]
}
如何查询属于 "mystery"
类别的所有图书?我知道我可以使用 allBooks(filter: {})
进行过滤,但是 categories_in: ["mystery"]
和 categories_contains: "mystery"
没有成功。
如果您有兴趣使用托管的 GraphQL 服务,scaphold.io 已经有一段时间了。 API 中的所有连接字段都带有一个 WhereArgs
参数,该参数公开过滤器,让您真正深入挖掘数据。当您有一个这样的标量列表时,WhereArgs 包含一个 contains
& notContains
字段,允许您根据列表中的值过滤结果。这允许您进行这样的查询。
query MysteriousBooks($where:BookWhereArgs) {
viewer {
allBooks(where:$where) {
edges { node { title, ... } }
}
}
}
# Variables
{
"where": {
"categories": {
"contains": "mystery"
}
}
}
为了完整起见,您还可以对架构进行轻微的重新调整,使这项工作无需在标量列表上进行过滤。例如,您可以使 Category
成为节点实现类型,然后在 Category
和 Book
之间创建连接。虽然 Book
可能不会有很多类别,但这将允许您发出这样的查询:
query MysteriousBooks($where: CategoryWhereArgs) {
viewer {
allCategories(where: $where) {
books {
edges { node { title, ... } }
}
}
}
}
# Variables
{
"where": {
"name": {
"eq": "mystery"
}
}
}
如果您以这种方式构建架构,那么您还可以对类别中的书籍进行更多过滤,而不必遍历档案中的每一本书。例如。你可以有效地要求 "all the mystery books written in the last year."
完全披露:我在 Scaphold 工作,尽管我希望您尝试一下,但如果您不转换,我不会感到难过。我很高兴看到人们尝试并热爱 GraphQL。如果您对如何在自己的服务器上实现此类行为感到好奇,请告诉我,我也很乐意为您提供帮助!
希望对您有所帮助!
Category
型号
考虑一下这种情况,创建一个 Category
模型绝对是可行的方法。
例如,假设您想允许读者稍后订阅他们喜欢的类别。或者,如果您想要所有现有类别的列表怎么办?使用字符串列表,您需要查询所有书籍并以某种方式对所有获得的类别进行后处理。在模型级别处理这个而不是使用字符串列表感觉更自然。
相反,您可以创建一个新的 Category
模型并在 Category
和 Book
之间添加多对多关系。在这种情况下,我喜欢添加一个唯一的枚举字段 tag
和一个字符串字段 text
。 (一个独特的字符串字段 tag
单独也是合适的,可能是个人喜好问题。)
使用此设置,您可以轻松满足
等数据要求哪些书籍被分配到给定类别?
query {
# query books by unique category tag
Category(tag: MYSTERY) {
books {
id
}
}
# query books by specific category text
Category(filter: {
text: "mystery"
}) {
books {
id
}
}
}
哪些书籍至少被分配到给定列表的一个类别?
query {
allCategories(filter: {
OR: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
哪些书被分配到给定列表的所有类别?
query {
allCategories(filter: {
AND: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
相关过滤器
即使上述查询满足指定的数据要求,书籍在响应中按 Category
分组,这意味着我们必须在客户端上展平分组。
使用所谓的相关过滤器,我们可以将其转换为仅根据定义相关类别的条件获取书籍。
例如,要查询 分配给给定列表中至少一个类别的图书:
query {
allBooks(filter: {
OR: [{
categories_some: {
tag: MYSTERY
},
categories_some: {
tag: MAGIC
}
}]
}) {
id
}
}