数组字段上的 GraphQL 过滤
GraphQL filtering on array field
我有一份文件,内容如下:
{
"data": {
"posts": [
{
"id": "5d9f1af799785458ed55fcf3",
"title": "Lorem ipsum dolor sit amet, consectetuer adipiscing eli",
"likedBy": {
"readers": [
"abc",
"xyz",
"mnp"
]
}
},
{
"id": "5d9f2afa9cf1b45a20edaf93",
"title": "Sed ut perspiciatis unde omnis iste natus error sit volupt",
"likedBy": null
},
{
"id": "5d9f2d1cd12ce45b11e90920",
"title": "But I must explain to you how all this mistaken idea of deno",
"likedBy": null
}
]
}
}
在这里,我有一个字段 likedBy
,它是一个以数组为值的对象。
现在,我可以运行以下查询来检索所有文档:
{
posts{
id
title
likedBy
}
}
但是,有什么方法可以在查询级别过滤掉数组的特定值吗?例如,假设我希望输出如下所示:
{
"data": {
"posts": [
{
"id": "5d9f1af799785458ed55fcf3",
"title": "Lorem ipsum dolor sit amet, consectetuer adipiscing eli",
"likedBy": {
"readers": [
"abc",
]
}
},
{
"id": "5d9f2afa9cf1b45a20edaf93",
"title": "Sed ut perspiciatis unde omnis iste natus error sit volupt",
"likedBy": null
},
{
"id": "5d9f2d1cd12ce45b11e90920",
"title": "But I must explain to you how all this mistaken idea of deno",
"likedBy": null
}
]
}
}
在这里,我像以前一样返回了所有文档,除了 likedBy
数组中只有 abc
。使用 GraphQL 可以吗?
是的,你可以。您可以在 graphql resolver
函数中实现过滤。即使您不使用 Apollo Server 来 运行 您的 graphql 服务器,link 到 the Apollo Server graphql resolver 也应该有所帮助。
如果您想通过名称是否以字母 "a" 开头来过滤 reader,即 "abc",它可能看起来像这样。我正在使用 SQL 查询来说明数据获取(例如 SELECT * FROM db_table),但您可以用任何方法替换它以从数据源(数据库,excel 文件、文档数据库等.)
// 您的查询
query($startsWith: String) {
posts{
id
title
likedBy(startsWith: $startsWith) {
readers
}
}
}
// 您随查询发送的变量/输入参数
{
"startsWith": "a"
}
// 您可能编写的解析器函数可以按 reader 的第一个字母表(或任何其他条件)进行过滤
const resolvers = {
Query: {
posts: function(root, args, context, info) {
return context.db.query('SELECT * FROM posts')
},
},
Posts: {
id: function(parent, args, context, info){
return parent.id // posts is the parent
},
title: function(parent, args, context, info){
return parent.title
},
likedBy: function(parent, args, context, info){
const postId = parent.id;
const targetAlphabet = args.startsWith; // <= This is where your input ends up
const allReadersWhoLikeThisPost = context.db.query(`SELECT DISTINCT * FROM readerLikes rl WHERE rl.liked_post_id = ${postId}`, 'collection')
const readerNames = allReadersWhoLikeThisPost.map(reader => reader.name)
// Filter for readers whose name starts with "a"
const filteredReaderNames = readerNames.filter(name => name.substring(0,1) === targetAlphabet)
const reshapedData = {
readers: filteredReaderNames
}
return reshapedData;
}
},
}
我有一份文件,内容如下:
{
"data": {
"posts": [
{
"id": "5d9f1af799785458ed55fcf3",
"title": "Lorem ipsum dolor sit amet, consectetuer adipiscing eli",
"likedBy": {
"readers": [
"abc",
"xyz",
"mnp"
]
}
},
{
"id": "5d9f2afa9cf1b45a20edaf93",
"title": "Sed ut perspiciatis unde omnis iste natus error sit volupt",
"likedBy": null
},
{
"id": "5d9f2d1cd12ce45b11e90920",
"title": "But I must explain to you how all this mistaken idea of deno",
"likedBy": null
}
]
}
}
在这里,我有一个字段 likedBy
,它是一个以数组为值的对象。
现在,我可以运行以下查询来检索所有文档:
{
posts{
id
title
likedBy
}
}
但是,有什么方法可以在查询级别过滤掉数组的特定值吗?例如,假设我希望输出如下所示:
{
"data": {
"posts": [
{
"id": "5d9f1af799785458ed55fcf3",
"title": "Lorem ipsum dolor sit amet, consectetuer adipiscing eli",
"likedBy": {
"readers": [
"abc",
]
}
},
{
"id": "5d9f2afa9cf1b45a20edaf93",
"title": "Sed ut perspiciatis unde omnis iste natus error sit volupt",
"likedBy": null
},
{
"id": "5d9f2d1cd12ce45b11e90920",
"title": "But I must explain to you how all this mistaken idea of deno",
"likedBy": null
}
]
}
}
在这里,我像以前一样返回了所有文档,除了 likedBy
数组中只有 abc
。使用 GraphQL 可以吗?
是的,你可以。您可以在 graphql resolver
函数中实现过滤。即使您不使用 Apollo Server 来 运行 您的 graphql 服务器,link 到 the Apollo Server graphql resolver 也应该有所帮助。
如果您想通过名称是否以字母 "a" 开头来过滤 reader,即 "abc",它可能看起来像这样。我正在使用 SQL 查询来说明数据获取(例如 SELECT * FROM db_table),但您可以用任何方法替换它以从数据源(数据库,excel 文件、文档数据库等.)
// 您的查询
query($startsWith: String) {
posts{
id
title
likedBy(startsWith: $startsWith) {
readers
}
}
}
// 您随查询发送的变量/输入参数
{
"startsWith": "a"
}
// 您可能编写的解析器函数可以按 reader 的第一个字母表(或任何其他条件)进行过滤
const resolvers = {
Query: {
posts: function(root, args, context, info) {
return context.db.query('SELECT * FROM posts')
},
},
Posts: {
id: function(parent, args, context, info){
return parent.id // posts is the parent
},
title: function(parent, args, context, info){
return parent.title
},
likedBy: function(parent, args, context, info){
const postId = parent.id;
const targetAlphabet = args.startsWith; // <= This is where your input ends up
const allReadersWhoLikeThisPost = context.db.query(`SELECT DISTINCT * FROM readerLikes rl WHERE rl.liked_post_id = ${postId}`, 'collection')
const readerNames = allReadersWhoLikeThisPost.map(reader => reader.name)
// Filter for readers whose name starts with "a"
const filteredReaderNames = readerNames.filter(name => name.substring(0,1) === targetAlphabet)
const reshapedData = {
readers: filteredReaderNames
}
return reshapedData;
}
},
}