简体   繁体   English

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

[英]MongoDB aggregation: Project separate document fields into a single array field

I have a document like this: 我有一个像这样的文件:

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

Is there a way to project (without a group stage) this document into this: 有没有一种方法可以将这个文档投影到这个文档中:

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

I could probably use a group stage operator for this, but I'd rather not if there's any other way, because my query also projects several other fields, all of which would require a $first just for the group stage. 我可以为此使用group stage运算符,但是如果有其他方法,我宁愿不要这样做,因为我的查询还计划了其他几个字段,所有这些字段仅在group stage时需要$first

Hope that's clear. 希望很清楚。 Thanks in advance! 提前致谢!

MongoDB 2.6 Introduces the the $map operator which is an array transformation operator which can be used to do exactly this: 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"
                 ]}
             }
        }}
    }}
])

So your document now looks exactly like you want. 因此,您的文档现在看起来完全像您想要的。 The trick of course to to create a new array with members "fax" and "cellphone", then transform that array with the new document fields by matching those values. 当然,技巧是创建一个具有成员“传真”和“手机”的新数组,然后通过匹配这些值将数组与新文档字段一起转换。

Of course you can also do this in earlier versions using $unwind and $group in a similar fashion, but just not as efficiently: 当然,您也可以在早期版本中使用$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"
            ]}
        }}
    }}
])

Of course it can be argued that unless you are doing some sort of aggregation then you may as well just post process the collection results in code. 当然可以说,除非您进行某种聚合,否则您最好只对代码中的收集结果进行后期处理。 But this is an alternate way to do that. 但这是另一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM