Add rootDoc $arg to GraphQL mappings
ujibang opened this issue · 1 comments
Brief overview
Allow to use {"$arg": "rootDoc"}
predefined variable to GraphQL query mapping and field to query/aggregation mappings.
Rationale
Given the following documents in a mongodb collection:
[
{
_id: 'foo',
_etag: ObjectId("64a6a6cde3acd23a25a20087"),
posts: [
{ content: 'ping', visible: true },
{ content: 'pong', visible: true },
{ content: 'invisible', visible: false }
]
},
{
_id: 'bar',
_etag: ObjectId("64a6a6cde3acd23a25a20087"),
posts: [
{ content: 'ping', visible: true },
{ content: 'pong', visible: true },
{ content: 'invisible', visible: false }
]
},
{
_id: 'zum',
_etag: ObjectId("64a6a6cde3acd23a25a20087"),
posts: [
{ content: 'ping', visible: true },
{ content: 'pong', visible: true },
{ content: 'invisible', visible: false }
]
}
]
Consider the following GraphQL schema
type User {
_id: String
posts(visible: Boolean): [Post]
}
type Post {
content: String
}
type Query {
users: [User]
}
In order to filter the nested document objects of the posts array we can make use of field to aggregation mapping:
{
"User": {
"posts": {
"db": "restheart",
"collection": "the-users",
"stages": [
{ "$match": { "_id": { "$fk": "_id" } } },
{ "$unwind" : "$posts" },
{ "$replaceRoot": {"newRoot": "$posts"} },
{ "$match": { "visible": { "$arg": "visible" } } }
]
}
}
}
It basically maps the posts
field to an aggregation that finds the root document, and applies stages to get the filtered posts
.
This solution relies on the $fk
operator to match the root document.
However this approach only works only for the first nesting level, i.e. if won't work for documents like the following:
{
"_id": "bar",
"sub": {
"posts": [
{ "content": "ping", "visible": true },
{ "content": "pong", "visible": true },
{ "content": "invisible", "visible": false }
]
}
}
The new predefined variable {"$arg": "rootDocId"}
will allow this use case:
{
"User": {
"posts": {
"db": "restheart",
"collection": "the-users",
"stages": [
{ "$match": { "_id": { "$arg": "rootDoc._id" } } }, <---
{ "$unwind" : "$sub.posts" },
{ "$replaceRoot": {"newRoot": "$sub.posts"} },
{ "$match": { "visible": { "$arg": "visible" } } }
]
}
}
}
Detailed documentation
https://restheart.org/docs/mongodb-graphql/#the-rootdoc-argument