Reputation: 2434
How can I collect all the subdocuments of a collection into a single array? Say I have these documents in my collection:
/* 0 */
{
"_id" : ObjectId("52d709d8cdcc16fa35834320"),
"start_date" : ISODate("2012-10-31T00:00:00.000Z"),
"end_date" : ISODate("2012-11-13T00:00:00.000Z"),
"items" : [
{
"upc" : "",
}
],
}
/* 1 */
{
"_id" : ObjectId("52d709d8cdcc16fa35834321"),
"modified_at" : ISODate("2014-01-15T22:16:06.991Z"),
"start_date" : ISODate("2012-10-31T00:00:00.000Z"),
"end_date" : ISODate("2012-11-13T00:00:00.000Z"),
"items" : [
{
"upc" : "",
}
],
}
/* 2 */
{
"_id" : ObjectId("654321973387fa1fa7777777"),
"start_date" : ISODate("2012-10-31T00:00:00.000Z"),
"end_date" : ISODate("2012-11-13T00:00:00.000Z"),
"items" : [
{
"upc" : "",
},
{
"upc" : "",
}
],
}
I don't need to do anyting fancy such as summing or calculating anything. I just want to extract the subdocuments and end up with this:
[
{ "upc" : "123" },
{ "upc" : "456" },
{ "upc" : "789" },
{ "upc" : "012" }
]
I know there has to be a simple way to do this, but I am not having any luck.
Upvotes: 1
Views: 566
Reputation: 300
I've done something similar, it can be achieved via the aggregation framework (http://docs.mongodb.org/manual/aggregation/). You could try a query like this ( Disclaimer : untested I usually build queries in C#)
db.collection.aggregate({
{ $unwind : "$items"},
{ $group: {
_id: null,
items:
{ $push: "$items" }
}}
}
If the syntax is correct, the query should hit every document and unwrap all the elements in the "items" array for every document. It then groups this together in a single document with "$group" and "$push" (operators explained here http://docs.mongodb.org/manual/reference/operator/aggregation/group/). This should produces a structure as such:
{
items:[
{ "upc" : "123" },
{ "upc" : "456" },
{ "upc" : "789" },
{ "upc" : "012" }"
]
}
if it produces more you should add a $project step at the end of the pipeline (http://docs.mongodb.org/manual/core/aggregation-pipeline/)(http://docs.mongodb.org/manual/reference/operator/aggregation/project/).
You can go further and optimize it by adding a $match step to filter the documents before unwinding, and even filter the results in the array ($match -> $unwind -> $match -> $group). (http://docs.mongodb.org/manual/reference/operator/aggregation/match/)
Hope this helps and GL!
Upvotes: 5