按字段聚合文档组

时间:2014-11-28 04:46:03

标签: mongodb aggregation-framework

我有一个带有特定字段的MongoDB集合,称之为target,如下所示:

{ "a": 123, "target": 1 }
{ "a": 456, "target": 2 }
{ "a": 324, "target": 3 }
{ "a": 333, "target": 1 }
{ "a": 678, "target": 1 }
{ "a": 789, "target": 2 }
{ "a": 555, "target": 3 }

我想知道是否有办法从概念上完成以下内容(如果不一定是字面意思):

[
   { "target": 1, [{ "a": 123, "target": 1 }, { "a": 333, "target": 1 }, { "a": 678, "target": 1 }] },
   { "target": 2, [{ "a": 456, "target": 2 }, { "a": 789, "target": 2 }] },
   { "target": 3, [{ "a": 324, "target": 3 }, { "a": 555, "target": 3 }] }
]

基本上,我希望将target值映射到包含这些目标值的所有文档,但阅读和重新阅读文档并没有帮助我弄清楚如何使用聚合执行此操作框架或其他任何东西。在我开始在我的应用程序代码中执行此操作之前,我想知道这是否可行。

2 个答案:

答案 0 :(得分:1)

AFAIK,无法创建包含所有结果的“单个数组”;但是你可以做的是为每个组(目标)创建一个文档,如下所述。

您可以通过在小组中执行$push来实现此目标

db.collection.aggregate([
  {$group : {  "_id" : "$target" , "values" :{ $push:  { a : "$a" , target : "$target"  }  } } },
  {$project : { "_id" : 0 ,  "values" : 1, "target" : "$_id" , }  }
]);

结果将类似于:

{
    "values": [
    {
        "a": 324,
        "target": 3
    },
    {
        "a": 555,
        "target": 3
    }
    ],
    "target": 3
}{
    "values": [
    {
        "a": 456,
        "target": 2
    },
    {
        "a": 789,
        "target": 2
    }
    ],
    "target": 2
}{
    "values": [
    {
        "a": 123,
        "target": 1
    },
    {
        "a": 333,
        "target": 1
    },
    {
        "a": 678,
        "target": 1
    }
    ],
    "target": 1
}

正如您所看到的,我已经为数组“values”添加了一个名称,因为您的结果示例不是有效的JSON文档

您还可以添加$out步骤,将此聚合的结果保存在新集合中

但是你必须非常小心这种聚合,因为你在结果中构建一个数组:请记住文档不能大于16Mb 。因此,如果您有太多“目标”条目,则可能达到此限制。

答案 1 :(得分:1)

您好,根据您的问题,我发现您可以通过某种方式实现这一目标,但这不符合您的预期,但它符合您的标准,汇总可能对您有所帮助

    db.collectionName.aggregate([
    {
    "$group": {
        "_id": {
            "a": "$a",
            "target": "$target"
        }
    }
    },
    {
    "$group": {
        "_id": "$_id.target",
        "targetData": {
            "$push": {
                "a": "$_id.a",
                "target": "$_id.target"
            }
        }
    }
    }
])