Reputation: 646
I have a schema that looks like this:
> db.test.findOne() { "_id" : "1:1419552000", "l0" : [ { "l1" : [ "1", "2", "3", "4" ] }, { "l1" : [ "11", "12", "13", "14" ] }, { "l1" : [ "21", "22", "23", "24" ] }, { "l1" : [ "31", "32", "33", "34" ] }, { "l1" : [ "41", "42", "43", "44" ] } ] }
I wish to be able to fetch a range of elements from within any of the arrays at level 1 (l1). But the $slice operator doesn't to be able to do that. Is this not possible at all?
> db.test.findOne({}, {"l0" : {$slice: 1}}) { "_id" : "1:1419552000", "l0" : [ { "l1" : [ "1", "2", "3", "4" ] } ] } > db.test.findOne({}, {"l0.0.l1" : {$slice: 2}}) { "_id" : "1:1419552000", "l0" : [ ... returns the entire object ... }
Any pointers or help is welcome. Thanks!
Upvotes: 1
Views: 966
Reputation: 34591
You can use the aggregation framework with $skip
, $limit
and $unwind
to get to the subarray range you need:
db.test.aggregate(
{
$match: { _id: "1:1419552000" }
},
{
$unwind: "$l0"
},
{
$limit: 1 // keeps the first element in l0
},
{
$unwind: "$l0.l1"
},
{
$limit: 2 // keeps the first two elements in the first l1
},
{
$group: // groups the unwound elements back into an array
{
_id: "$_id",
l0: { $addToSet: "$l0.l1" }
}
}
)
This will be returned:
{ "_id" : "1:1419552000", "l0" : [ "2", "1" ] }
Upvotes: 2
Reputation: 21766
You don't specify the required output in your question. Assuming you only want to return elements of l1
that meet a certain range criteria (e.g >41) you could use the $unwind
parameter and the aggregate
function:
db.test.aggregate({
$unwind: "$l0"
}, {
$unwind: "$l0.l1"
}, {
$match: {
"l0.l1": {
$gt: "41"
}
}
}, {
"$group": {
"_id": "$_id",
"l1": {
"$addToSet": "$l0.l1"
}
}
})
This will return:
{
"_id": "1:1419552000",
"l1": ["43", "44", "42"]
}
If you add the required output to your question, I can modify the query to return the correct output.
Upvotes: 2
Reputation: 824
For the sample document you provided, db.test.findOne({}, {"l0.l1" : {$slice: 2}})
returns
{
"_id" : "1:1419552000",
"l0" : [
{
"l1" : [
"1",
"2"
]
},
{
"l1" : [
"11",
"12"
]
}, ...
Upvotes: -1