I have a model Book with a field "tags" which is of type array of String / GraphQLString.
Currently, I’m able to query the tags for each book.
{
books {
id
tags
}
}
and I get the result:
{
"data": {
"books": [
{
"id": "631664448cb20310bc25c89d",
"tags": [
"database",
"middle-layer"
]
},
{
"id": "6316945f8995f05ac71d3b22",
"tags": [
"relational",
"database"
]
},
]
}
}
I want to write a RootQuery where I can fetch all unique tags across all books. This is how far I am (which is not too much):
tags: {
type: new GraphQLList(GraphQLString),
resolve(parent, args) {
Book.find({}) // CAN'T FIGURE OUT WHAT TO DO HERE
return [];
}
}
Basically, I’m trying to fetch all books and then potentially merge all tags fields on each book.
I expect that if I query:
{
tags
}
I would get
["relational", "database", "middle-layer"]
I am just starting with Mongoose, MongoDB, as well as GraphQL, so not 100% sure what keywords to exactly look fo or even what the title of this question should be.
Appreciate the help.
2
Answers
MongoDb + JavaScript Solution
This returns an array of objects that contain only the
tags
value.$project
is staging this item in the aggregation pipeline by selecting keys to include, denoted by1
or0
._id
is added by default so it needs to be explicitly excluded.Then take the
tags
array that looks like this:And reduce it to be one unified array, then make it into a javascript
Set
, which will exclude duplicates by default. I convert it back to an Array at the end, if you need to perform array methods on it, or write back to the DB.Pure MongoDB Solution
Steps in Aggregation Pipeline
$unwind
tags
$group
tags
_id
is a required field_id
will be excluded from the final aggregation so it doesn’t matter what it is$project
_id
from the resultsOutput
Mongo Playground Demo
While this solution gets the result with purely Mongo queries, the resulting output is nested and still requires traversal to get to desired fields. I do not know of a way to replace the root with a list of string values in an aggregation pipeline. So at the end of the day, JavaScript is still required.
You want to
$unwind
the arrays so they’re flat, at that point we can just use$group
to get unique values. like so:Mongo Playground