如何将所有子文档收集到一个数组中

时间:2014-01-16 19:09:50

标签: mongodb mongoose

如何将集合的所有子文档收集到一个数组中?说我在我的收藏中有这些文件:

/* 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" : "",
        }
    ],
}

我不需要做任何花哨的事情,例如总结或计算任何东西。我只想提取子文档并最终得到:

[
    { "upc" : "123" },
    { "upc" : "456" },
    { "upc" : "789" },
    { "upc" : "012" }
]

我知道必须有一个简单的方法来做到这一点,但我没有运气。

1 个答案:

答案 0 :(得分:5)

我做过类似的事情,可以通过聚合框架(http://docs.mongodb.org/manual/aggregation/)来实现。您可以尝试这样的查询(免责声明:未经测试我通常在C#中构建查询)

db.collection.aggregate({
   { $unwind : "$items"}, 
   { $group: { 
      _id: null, 
      items: 
        { $push: "$items" } 
   }} 
}

如果语法正确,则查询应该点击每个文档,并为每个文档打开“items”数组中的所有元素。然后,它将这个组合在一个单独的文档中,其中包含“$ group”和“$ push”(运算符在这里解释http://docs.mongodb.org/manual/reference/operator/aggregation/group/)。这个生成一个结构:

{
   items:[
      { "upc" : "123" },
      { "upc" : "456" },
      { "upc" : "789" },
      { "upc" : "012" }"
   ] 
}

如果产生更多,则应在管道末尾添加$ project步骤(http://docs.mongodb.org/manual/core/aggregation-pipeline/)(http://docs.mongodb.org/manual/reference/operator/aggregation/project/)

您可以进一步优化它,在展开前添加$ match步骤来过滤文档,甚至过滤数组中的结果($ match - > $ unwind - > $ match - > $ group) 。 (http://docs.mongodb.org/manual/reference/operator/aggregation/match/

希望这有助于GL!