使用键值对将mongo数组转换为对象

时间:2016-09-23 06:21:24

标签: mongodb meteor mongodb-query aggregation-framework mongodb-aggregation

我有一个包含字符串数组的mongo文档,我需要将这个特定的字符串数组转换为包含键值对的对象数组。以下是我对它的不切实际的评价。

{
    "_id" : ObjectId("57e3720836e36f63695a2ef2"),
    "platform" : "A1",
    "available" : {
        "Community" : {
            "attributes" : {
                "type" : {
                    "values" : [
                        "well-known",
                        "simple",
                        "complex"
                    ],
                    "defaultValue" : "well-known"
                },
[......]


}

当前查询:

templateAttributes.find({platform:"V1"}).map(function(c){
  //instantiate a new array
  var optionsArray = [];
for (var i=0;i< c['available']['Community']['attributes']['type']['values'].length; i++){
    optionsArray[i] = {};              // creates a new object
    optionsArray[i].label = c['available']['Community']['attributes']['type']['values'][i];
    optionsArray[i].value = c['available']['Community']['attributes']['type']['values'][i];
    }
    return optionsArray;
})[0];

结果:

[{label:"well-known", value:"well-known"},
{label:"simple", value:"simple"},
{label:"complex", value:"complex"}]

我的方法是否足够有效,或者有没有办法优化上述查询以获得相同的预期结果?

3 个答案:

答案 0 :(得分:3)

请在此处使用聚合。

db.templateAttributes.aggregate([
                                    {"$match":{platform:"A1"}}, {"$unwind": "$available.Community.attributes.type.values"}, 
                                    {$group: {"_id": null, "val":{"$push":{label:"$available.Community.attributes.type.values", 
                                                                            value:"$available.Community.attributes.type.values"}}}}
                                ]).toArray()[0].val

<强>输出:

[
    {
            "label" : "well-known",
            "value" : "well-known"
    },
    {
            "label" : "simple",
            "value" : "simple"
    },
    {
            "label" : "complex",
            "value" : "complex"
    }
]

答案 1 :(得分:3)

不太确定你想要对最终结果做什么,因为键和值是一样的。但是,您可以使用聚合框架 您可以使用 $unwind 运算符对嵌入值数组进行非规范化处理,该运算符将其展平,即每个数组条目生成每个文档的副本。

展平值数组后,您可以对值应用 $group 累加运算符来聚合它们。 $project 运算符的最终管道会将先前分组中的字段整形为所需格式。

按照此示例获取概念:

templateAttributes.aggregate([
    { "$match": { "platform": "V1" } },
    { "$unwind": "$available.Community.attributes.type.values" },
    {
        "$group": {
            "_id": "$available.Community.attributes.type.values",
            "value": { "$first": "$available.Community.attributes.type.values" }
        }
    },
    {
        "$project": {
            "_id": 0,
            "label": "$_id",
            "value": 1
        }
    }
])

由于您使用Meteor,meteor add meteorhacks:aggregate 将为Meteor添加适当的聚合支持,以便您可以在集合上运行上述聚合管道。

答案 2 :(得分:0)

使用查询

  templateAttributes.aggregate([{
$match: {
    "platform" : "A1"
    }},
    {
    $unwind: {path : "$available.Community.attributes.type.values"}},{   $group:{
    _id:"$_id",
    result:{
        $push: {
            label: "$available.Community.attributes.type.values", value: "$available.Community.attributes.type.values"
            }
        }
    }}])

它会准确地给出您的预期答案。