MongoDB聚合:将单独的文档字段投影到单个数组字段中

时间:2015-02-03 21:56:23

标签: mongodb mongodb-query aggregation-framework

我有这样的文件:

{fax: '8135551234', cellphone: '8134441234'}

有没有办法将此文档投影(没有小组阶段):

{
    phones: [{
        type: 'fax',
        number: '8135551234'
    }, {
        type: 'cellphone',
        number: '8134441234'
    }]
}

我可能会使用一个组阶段运算符,但是我不想是否有其他任何方式,因为我的查询还会预测其他几个字段,所有这些字段都需要$first仅用于该组阶段。

希望很清楚。提前谢谢!

1 个答案:

答案 0 :(得分:4)

MongoDB 2.6引入$map运算符,它是一个数组转换运算符,可用于完成此操作:

db.phones.aggregate([
    { "$project": {
        "phones": { "$map": {
            "input": { "$literal": ["fax","cellphone"] },
            "as": "el",
            "in": {
                "type": "$$el",
                "number": { "$cond": [
                     { "$eq": [ "$$el", "fax" ] },
                     "$fax",
                     "$cellphone"
                 ]}
             }
        }}
    }}
])

因此,您的文档现在看起来完全符合您的要求。当然要创建一个包含成员的新数组" fax"和"手机",然后通过匹配这些值,使用新文档字段转换该数组。

当然,您也可以使用$unwind$group以类似的方式在早期版本中执行此操作,但效率不高:

db.phones.aggregate([
    { "$project": {
        "type": { "$const": ["fax","cellphone"] },
        "fax": 1,
        "cellphone": 1
    }},
    { "$unwind": "$type" },
    { "$group": {
        "_id": "_id",
        "phones": { "$push": { 
            "type": "$type",
            "number": { "$cond": [
                { "$eq": [ "$type", "fax" ] },
                "$fax",
                "$cellphone"
            ]}
        }}
    }}
])

当然可以说,除非你正在进行某种聚合,否则你也可以只在代码中处理收集结果。但这是另一种方法。