【问题标题】:mongodb, how can I project or push root field on nested array using aggregate?mongodb,如何使用聚合在嵌套数组上投影或推送根字段?
【发布时间】:2020-09-25 05:05:22
【问题描述】:

我有以下包含四个嵌套数组的示例文档

{
    "_id" : ObjectId("5ed6bd9596908c36f4200980"),
    "attr2" : "hello",
    "attr3" : 1234,
    "attr1" : {
        "firstArray" : [
            {
                "secondArray" : [
                    {
                        "secondAttr1" : "world",
                        "secondAttr2" : 456,
                        "secondAttr3" : [
                            {
                                "finalArray" : [
                                    {
                                        "finalAttr1" : "alex",
                                        "finalAttr2" : 9876
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }

}

这个聚合查询通过嵌套数组查找,展开并为每个处理的数组创建新根,从“finalArray”返回元素

db.AssetTest.aggregate(
[
    {'$match':{'$and':[{'attr2': {'$eq':'hello'}}]}},
    {'$project': {'values': '$attr1.firstArray'}},
    {'$unwind':'$values'},
    {'$replaceRoot':{'newRoot':'$values'}},

    {'$project': {'values': {'$filter': {'input': '$secondArray','cond': {'$and':[{'$eq':['$$this.secondAttr1', 'world']}]}}}}},
    {'$unwind':'$values'},
    {'$replaceRoot':{'newRoot':'$values'}},

    {'$project': {'values': '$secondAttr3'}},
    {'$unwind':'$values'},
    {'$replaceRoot':{'newRoot':'$values'}},

    {'$project': {'values': {'$filter': {'input': '$finalArray','cond': {'$and':[{'$eq':['$$this.finalAttr1', 'alex']}]}}}}},
    {'$unwind':'$values'},
    {'$replaceRoot':{'newRoot':'$values'}}

    ]
)

这个聚合的结果是

{
    "finalAttr1" : "alex",
    "finalAttr2" : 9876
}

我的问题是,我怎样才能通过所有聚合阶段投影根字段“attr2”,以便它将在结果数组上?

{
    "attr2"      : "hello",
    "finalAttr1" : "alex",
    "finalAttr2" : 9876
}

我是 mongo 的新手,对此我完全迷失了,所以非常感谢任何帮助。

顺便说一句,我使用的是 mongo 3.4.15。

非常感谢!!

【问题讨论】:

    标签: arrays mongodb mongodb-query aggregation-framework


    【解决方案1】:

    在您的情况下,您需要的只是 $addFields,它已在 MongoDB 版本 3.4 中引入:

    我已经减少了一些似乎没有用的阶段和操作符,检查这个最新的聚合管道:

    db.collection.aggregate([
        {
          "$match": { "attr2": "hello" }
        },
        /** This stage adds new field to the place where you want */
        {
          $addFields: { "attr1.firstArray.secondArray.secondAttr3.finalArray.attr2": "$attr2" }
        },
        {
          "$unwind": "$attr1.firstArray"
        },
        {
          "$replaceRoot": { "newRoot": "$attr1.firstArray" }
        },
        {
          "$project": {
            "secondArray": {
              "$filter": { "input": "$secondArray", "cond": { "$eq": [ "$$this.secondAttr1", "world" ] } }
            }
          }
        },
        {
          "$unwind": "$secondArray"
        },
        {
          "$replaceRoot": { "newRoot": "$secondArray" }
        },
        {
          "$unwind": "$secondAttr3"
        },
        {
          "$replaceRoot": { "newRoot": "$secondAttr3" }
        },
        {
          "$project": {
            "finalArray": { "$filter": { "input": "$finalArray", "cond": { "$eq": [ "$$this.finalAttr1", "alex" ] } } }
          }
        },
        {
          "$unwind": "$finalArray"
        },
        {
          "$replaceRoot": { "newRoot": "$finalArray"}
        }
      ])
    

    测试: mongoplayground

    参考:$addFields

    注意:

    1. 您无需在单一条件下使用$and(请参阅您的第一阶段)。
    2. 您不需要在中间多个$project 阶段进行转换(请参阅您的第二阶段)。

    【讨论】:

    • 感谢 whoami,完美运行。谢谢你的笔记,我需要和 mongo 再打一架 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多