zoukankan      html  css  js  c++  java
  • 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/

    (完)

  • 相关阅读:
    面向对象程序设计寒假作业2
    面向对象程序设计寒假作业1
    自我介绍
    3组-Alpha冲刺-1/6
    3组 需求分析报告
    3组 团队展示
    第一次个人编程作业
    第一次博客作业
    我罗斯方块最终篇
    我罗斯方块设计
  • 原文地址:https://www.cnblogs.com/wzs5800/p/12861279.html
Copyright © 2011-2022 走看看