Reputation: 2863
I have a document with the following contents:
{
"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
}
]
}
}
Here, I have a field likedBy
which is an object with an array as its value.
Now, I can run the following query to retrieve all documents:
{
posts{
id
title
likedBy
}
}
However, is there any way to filter out specific values of the array at the query level? For instance, Say I want my output to look like this:
{
"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
}
]
}
}
Here, I have returned all documents as before, except with only abc
in the likedBy
array. Is that possible with GraphQL?
Upvotes: 1
Views: 732
Reputation: 346
Yes, you can. You can implement filtering at the graphql resolver
function. This link to the Apollo Server graphql resolver should help even if you don't use Apollo Server to run your graphql server.
Here's what it could look like if you wanted to filter the reader by whether their name started with the letter "a", i.e. "abc". I am using SQL queries to illustrate data fetching (e.g. SELECT * FROM db_table) but you can replace it with any method to fetch data from a data source (database, excel file, document db, etc..)
// your query
query($startsWith: String) {
posts{
id
title
likedBy(startsWith: $startsWith) {
readers
}
}
}
// the variables / input arguments you send with your query
{
"startsWith": "a"
}
// The resolver function you might write that can filter by the reader's first alphabet (or any other condition)
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;
}
},
}
Upvotes: 3