如何在同一结果中将两个单独的聚合组合在一起

时间:2015-12-01 21:42:19

标签: mongodb aggregation-framework

我想要两个聚合并将它们组合在一起。 “Blakes Seven”通过几个查询帮助我检索第一个和第二个数组元素值,但我需要两个一起。

第一个:

db.getCollection('anothertest').aggregate([
{ "$unwind": "$a" },
{ "$group": {
    "_id": "$_id",
    "first": { "$first": "$a" }
}}
])

给出结果:

{
"result" : [ 
    {
        "_id" : ObjectId("565cc5261506995581569439"),
        "first" : 4
    }
],
"ok" : 1.0000000000000000
}

第二个:

db.getCollection('anothertest').aggregate([
{ "$unwind": "$a" },
// Keeps the first element
{ "$group": {
    "_id": "$_id",
    "first": { "$first": "$a" },
    "a": { "$push": "$a" }
 }},
{ "$unwind": "$a" }
,
// Removes the first element
{ "$redact": {
"$cond":{
"if": { "$ne": [ "$first", "$a" ] },
"then": "$$KEEP",
  "else": "$$PRUNE"
}
}}

给出结果:

{
"result" : [ 
    {
        "_id" : ObjectId("565cc5261506995581569439"),
        "second" : 2
    }
],
"ok" : 1.0000000000000000
}

我需要的是:

的结果
{
"result" : [ 
    {
        "_id" : ObjectId("565cc5261506995581569439"),
        "first" : 4
        "second" : 2
    }
],
"ok" : 1.0000000000000000
}

除此之外,它所基于的文档只是一个例子,其中值作为数组中的元素。我如何在嵌套数组上使用它?如果这对于聚合来说是复杂的,那么使用Map Reduce可能有更简单的方法来实现这一点吗?感谢您提供的任何帮助。

以上文件如下:

{
"_id" : ObjectId("565cc5261506995581569439"),
"a" : [ 
    4, 
    2, 
    8, 
    71, 
    21
]
}

更新我的原始帖子 我现在设法采用了令人敬畏的脚本,并使其适用于我的具有嵌套数组的文档 - 直到某一点。

{ "$match": {objectOriginAPI : "Profit & Loss"}},
{ "$unwind": "$objectRawOriginData.Reports" },
        { "$unwind": "$objectRawOriginData.Reports.Rows" },
        { "$unwind": "$objectRawOriginData.Reports.Rows.Rows" },
        { "$unwind": "$objectRawOriginData.Reports.Rows.Rows.Cells" },
{ "$group": {
    "_id": "$_id",
    "first": { "$first": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" },
    "a": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
{ "$unwind": "$a" },
{"$skip":1},
{ "$group": {
    "_id": "$_id",
    "BalanceName": { "$first": "$first" },
    "BalanceValue": { "$first":      "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" },
}}
])

实际上,我不小心忘了更新第二个$ unwind,所以它仍然是“$ a”。发生的事情是我得到了以下结果:

{
"result" : [ 
    {
        "_id" : ObjectId("564d12da1506995581569428"),
        "BalanceName" : "Sales",
        "BalanceValue" : null
    }
],
"ok" : 1.0000000000000000
}

但是当我更改$ unwind以匹配第一个值的$ unwind时,我根本没有得到任何结果。我无法理解为什么,任何想法?谢谢,马特

1 个答案:

答案 0 :(得分:1)

您可以按照与您发布的第一个聚合相同的逻辑执行此操作。请注意,我使用$skip跳过第一个数组元素并获取第二个数组元素。

db.collection.aggregate([
    { "$match": {
        "_id": ObjectId("565cc5261506995581569439")
    }},
    { "$unwind": "$a" },
    { "$group": {
        "_id": "$_id",
        "first": { "$first": "$a" },
        "a": { "$push": "$a" }
    }},
    { "$unwind": "$a" },
    {"$skip":1},
    { "$group": {
        "_id": "$_id",
        "first": { "$first": "$first" },
        "second": { "$first": "$a" },
    }}
])

结果:

{ 
    "_id" : ObjectId("565cc5261506995581569439"),
    "first" : 4,
    "second" : 2 
}

您的第二个聚合也非常接近所需的输出:

db.collection.aggregate([
    { "$match": {
        "_id": ObjectId("565cc5261506995581569439")
    }},
    { "$unwind": "$a" },
    { "$group": {
        "_id": "$_id",
        "first": { "$first": "$a" },
        "a": { "$push": "$a" }
    }},
    { "$unwind": "$a" },
    { "$redact": {
        "$cond":{
        "if": { "$ne": [ "$first", "$a" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
    }}},
    { "$limit": 1},
    { "$project": {
        "_id":1,
        "first":1,
        "second":"$a"
    }}
])

编辑:此外,实际上,这两种聚合仅适用于单个文档,因此需要添加初始$match步骤。