Reputation: 245
I want to run a query to select specific documents. Then on each document, open up an array of sub documents and run a query to filter those sub docs.
Example:
{
"_id" : ObjectID(23412351346435),
"list" : [
{date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"},
{date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"},
{date: ISODate(2015-01-14T00:00:00.000Z), name: "Jan 14"}
]
}
I'm guessing I can do something with Mongo's aggregate
function. I have been able to match the documents I want, but how can I get a sub query going on the array? I tried using $elemMatch
but that only returns the first item in the array that matches the date range.
To be clear when I query for ObjectID(23412351346435)
and Date range 2015-01-12 to 2015-01-13 I want it to return this;
{
"_id" : ObjectID(23412351346435),
"list" : [
{date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"},
{date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"}
]
}
Upvotes: 1
Views: 1661
Reputation: 3879
As you guessed, you can use aggregation
to get the results you are looking for. The steps you need in your aggregation pipeline are the following.
_id
).list
array._id
.Your query should look something like this:
db.collection.aggregate([
{ "$match": { "_id": ObjectId("54ef8b0acfb269d664de0b48")} },
{ "$unwind": "$list" },
{ "$match": {
"list.date": { $gte: ISODate("2015-01-12T00:00:00.000Z"),
$lte: ISODate("2015-01-13T00:00:00.000Z")
}
}},
{ "$group": {
"_id": "$_id",
"list": { "$push": { "date": "$list.date", "name": "$list.name" }}
}}
]);
Upvotes: 2
Reputation: 14900
You can use the $unwind operator. It allows you to take an array in a document, and clone that document with each of the array elements. Then you can match on the field. If necessary, you can use $group to wind the document back up.
[
{$match:{...}},
{$unwind:"myfield"},
{$match:{"myfield.name":"Jan 12"}},
{$group:{ _id:"$id", "myfield":{$push:"$myfield"} }}
]
Note that $unwind is slow for large sets of documents, and combinatoric for multiple arrays. It is the only option you really have for Mongo 2.4.x though. You might be better served by rearranging your data so that you do not have arrays.
Upvotes: 1