用对象列表替换字符串列表 - mongoDB

时间:2015-09-03 12:36:48

标签: javascript mongodb mongodb-query

我有一个mongo对象,当前有一个字符串列表,见下​​文。

{
    "_id" : "One-123-1439251200000",
    "string_list" : [ 
        "123", 
        "321"
    ],
}

我在创建mongo脚本时遇到了麻烦,该脚本会将此字符串列表转换为对象列表(该对象列表中的某个属性为每个字符串)。见下文......

{
    "_id" : "One-123-1439251200000",
    "detailed_string_list" : [ 
    {
        "id" : "123",
        "label" : ""
    }, 
    {
        "id" : "321",
        "label" : ""
    }, 
}

任何人都可以帮我创建这个小脚本吗?我曾试图查看MongoDB manual,但它没有做我正在寻找的事情(可能做错了。非常感谢。

EDIT。我正在迭代一堆记录,我正在尝试

.forEach(function(doc) {

_id字段是我不需要更改的唯一ID

2 个答案:

答案 0 :(得分:1)

在聚合中使用 $literal ,如下所示:

db.collectionName.aggregate({
  "$unwind": "$string_list"
}, {
  "$group": {
    "_id": "$_id",
    "detailed_string_list": {
      "$push": {
        "id": "$string_list",
        "label": {
          "$literal": ""
        }
      }
    }
  }
}).pretty()

使用 $map

db.collectionName.aggregate({
  "$project": {
    "detailed_string_list": {
      "$map": {
        "input": "$string_list",
        "as": "el",
        "in": {
          "id": "$$el",
          "label": {
            "$literal": ""
          }
        }
      }
    }
  }
}).pretty()

答案 1 :(得分:1)

作为“更新”操作,然后使用"Bulk"操作将极大地帮助您:

var bulk = db.collection.initializeOrderedBulkOp(),
    count = 0;

db.collection.find({ "string_list": { "$exists": true } } ).forEach(function(doc) { 
    bulk.find({ "_id": doc._id }).updateOne({ "$unset": { "string_list": "" } });

    doc.string_list.forEach(function(list) {
        bulk.find({ "_id": doc._id }).updateOne({
            "$push": { 
                "detailed_string_list": { 
                    "_id": list,
                    "label": ""
                }
            }
        });
    });
    count++;

    if ( count % 200 == 0 ) {
        bulk.execute();
        var bulk - db.collection.initializeOrderedBulkOp();
    }
]);

if ( count % 200 != 0 )
    bulk.execute();

作为一般的“转换”,您可以使用$map但是不可能在该过程中使用生成的值注入“_id”之类的字段,但您可以只使用当前值或常量。但是你最好在客户端代码中执行此操作,例如(javascript和shell),这通常会更有效:

   var results = \\ general .find() cursor result
   var counter = 0;

   results = results.map(function(result){ 
       result.detailed_string_list = results.string_list.map(function(list) {
           return { "_id": list, "label": "" };
       });
       delete result.string_list;
       return result;
   });

但是当然如果您的MongoDB版本低于2.6,那么您就无法使用批量操作,只需要在循环中使用基本更新:

db.collection.find({ "string_list": { "$exists": true } } ).forEach(function(doc) { 
    db.collection.update({ "_id": doc._id },{ "$unset": { "string_list": "" } });

    doc.string_list.forEach(function(list) {
        db.collection.update(
            { "_id": doc._id },
            {
                "$push": { 
                    "detailed_string_list": { 
                        "_id": list,
                        "label": ""
                    }
                }
            }
        );
    });
]);