mongo 使用聚合合並字段


使用聚合合並字段

需求

有時候,我們需要在查詢結果中將某個字段(數組)合並起來,返回一個數組即可。

例子

假設集合user:

{ 
    "_id" : ObjectId("5eb6bb5bc95fdd10d0f6d21e"), 
    "name" : "小明", 
    "education" : "本科", 
    "experiences" : [
        {
            "profession" : "程序員", 
            "ability" : [
                "java", 
                "nodejs", 
                "golang"
            ]
        }
    ]
}
// ----------------------------------------------
{ 
    "_id" : ObjectId("5eb6bbdbc95fdd10d0f6d220"), 
    "name" : "小紅", 
    "education" : "本科", 
    "experiences" : [
        {
            "profession" : "銷售", 
            "ability" : [
                "溝通", 
                "財務計算"
            ]
        }, 
        {
            "profession" : "采購員", 
            "ability" : [
                "英語", 
                "統計"
            ]
        }
    ]
}
// ----------------------------------------------
{ 
    "_id" : ObjectId("5eb6bdbbc95fdd10d0f6d23f"), 
    "name" : "小三", 
    "education" : "大專", 
    "experiences" : [
        {
            "profession" : "行政助理", 
            "ability" : [
                "英語"
            ]
        }
    ]
}

接下來我想查詢出所有學歷為“本科”的閱歷(experiences)列表,並把它們合並成一個數組返回,如:

{ 
    "_id" : "1", 
    "experiences" : [
        { "profession" : "銷售", "ability" : ["溝通", "財務計算"] }, 
        { "profession" : "采購員", "ability" : ["英語",  "統計"]}, 
        { "profession" : "程序員", "ability" : ["java", "nodejs", "golang"]}
    ]
}

實現

使用Aggregate來實現。

db.getCollection("user").aggregate(
    [
        { 
            "$match" : { "education" : "本科" }
        }, 
        { 
            "$group" : {
                "_id" : "1", 
                "experiences" : {
                    "$addToSet" : "$experiences"
                }
            }
        }, 
        { 
            "$project" : {
                "experiences" : {
                    "$reduce" : {
                        "input" : "$experiences", 
                        "initialValue" : [], 
                        "in" : { "$concatArrays" : ["$$value", "$$this"] }
                    }
                }
            }
        }
    ]
);

說明:

  • $match: 選擇器,篩選的條件,這里查詢出學歷(education)為本科的數據。
  • $group: 相當於sql中的group by, 例子中的"_id"只是用於分組的標識,“experiences“設置分組返回到哪個字段上,相當於as。
  • $addToSet: 不重復添加到數組。

到這里,會把學歷為“本科”的閱歷全部查出來,數據是這樣子:

{ 
    "_id" : "1", 
    "experiences" : [
        [
            {"profession" : "銷售",  "ability" : [ "溝通",  "財務計算" ]}, 
            {"profession" : "采購員", "ability" : [ "英語",  "統計" ]}
        ], 
        [
            {"profession" : "程序員",  "ability" : ["java", "nodejs", "golang"]}
        ]
    ]
}

但這還不是我們要的結果,使用$project再次處理,所有experiences追加

{ 
    "$project" : {
        "experiences" : {
            "$reduce" : {
                "input" : "$experiences", 
                "initialValue" : [],
                "in" : { "$concatArrays" : ["$$value", "$$this"] }
            }
        }
    }
}  

說明:

  • $project: 接受一個文檔,該文檔可以指定包含字段、禁止顯示id字段、添加新字段以及重置現有字段的值。或者,可以指定排除字段。
  • $reduce:將"in"里的表達式應用到"input"數組里,並將它們合並成一個數組。
  • "in"里面的表達式可以很靈活的對數組操作,這里用的$concatArrays將experiences[]字段里的元素連接起來。

最后結果:

{ 
    "_id" : "1", 
    "experiences" : [
        { "profession" : "銷售", "ability" : ["溝通", "財務計算"] }, 
        { "profession" : "采購員", "ability" : ["英語",  "統計"]}, 
        { "profession" : "程序員", "ability" : ["java", "nodejs", "golang"]}
    ]
}

參考

https://docs.mongodb.com/manual/reference/operator/aggregation/reduce/

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM