Reputation: 2459
I am storing some tree-structured data in MongoDB. It looks something like this:
{
"_id": 1,
"name": "foo",
"subs": [{
"name": "bar",
"subs": [{
"name": "baz"
},
{
"name": "gizmo"
}]
}]
}
{
"_id": 2,
"name": "foo",
"subs": [{
"name": "bar",
"subs": [{
"name": "gizmo"
}]
}]
}
I want to query on the subtrees, and wish only to extract the part of the tree that matches the query. In each node, there is at most one subtree that matches the query.
In this test-query, I want to find the part of the tree that matches the path "foo/bar/gizmo". So, I have tried the following:
db.Test.find({
name: "foo",
subs: {
$elemMatch: {
name: "bar",
subs: {
$elemMatch: {
name: "gizmo"
}
}
}
}
},
{
"subs.subs": {
$slice: 1
}
})
The result I get is
{
"_id": 1,
"name": "foo",
"subs": [{
"name": "bar",
"subs": [{
"name": "baz"
}]
}]
}{
"_id": 2,
"name": "foo",
"subs": [{
"name": "bar",
"subs": [{
"name": "gizmo"
}]
}]
}
whereas I actually wanted
{
"_id": 1,
"name": "foo",
"subs": [{
"name": "bar",
"subs": [{
"name": "gizmo"
}]
}]
}{
"_id": 2,
"name": "foo",
"subs": [{
"name": "bar",
"subs": [{
"name": "gizmo"
}]
}]
}
Is it possible to do this? I have tried using the $elemMatch
projection operator on the subtrees, but it seems it is not currently supported by Mongo (Cannot use $elemMatch projection on a nested field (currently unsupported)).
Upvotes: 1
Views: 575
Reputation: 26012
You can use Aggregation Framework to get result as you wish. Try the following code :
db.Test.aggregate(
{$unwind : "$subs"},
{$unwind : "$subs.subs"},
{$match : {name : "foo", "subs.name" : "bar", "subs.subs.name" : "gizmo"}}
);
Result will be like :
"result" : [
{
"_id" : ObjectId("52540da2e3a2c44e082642d4"),
"name" : "foo",
"subs" : {
"name" : "bar",
"subs" : {
"name" : "gizmo"
}
}
},
{
"_id" : ObjectId("52540dd6e3a2c44e082642d5"),
"name" : "foo",
"subs" : {
"name" : "bar",
"subs" : {
"name" : "gizmo"
}
}
}
]
Upvotes: 0