MongoDB:列表中的几个字段

标签 mongodb mongodb-query

我目前有一个遵循如下格式的集合:

{ "_id": ObjectId(...),
  "name" : "Name",
  "red": 0,
  "blue": 0,
  "yellow": 1,
  "green": 0,
  ...}

等等(一堆颜色)。我想做的是创建一个名为 colors 的新数组,其元素是值为 1 的那些颜色。

例如:

{ "_id": ObjectId(...),
  "name" : "Name",
  "colors": ["yellow"]
}

这是我可以在 Mongo shell 上做的事情吗?还是我应该在程序中做? 我很确定我可以使用 Python 来完成它,但是我在尝试直接在 shell 中进行操作时遇到了困难。如果可以在 shell 中完成,谁能指出正确的方向?

谢谢。

最佳答案

是的,它可以在 shell 中轻松完成,或者基本上按照适用于任何语言的示例进行操作。

这里的关键是查看“颜色”字段,然后构造一个更新语句,从文档中删除这些字段,同时测试它们是否有效以包含到数组中,然后当然添加以及文档更新:

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

db.collection.find().forEach(function(doc) { 

    doc.colors = doc.colors || [];

    var update = { "$unset": {}};
    Object.keys(doc).filter(function(key) { 
        return !/^_id|name|colors/.test(key) 
    }).forEach(function(key) {
        update.$unset[key] = "";
        if ( doc[key] == 1)
            doc.colors.push(key);
    });

    update["$addToSet"] = { "colors": { "$each": doc.colors } };

    bulk.find({ "_id": doc._id }).updateOne(update);
    count++;

    if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.collection.initializeOrderedBulkOp()
    }

});

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

Bulk Operations使用意味着发送批量更新而不是每个文档一个请求和响应,因此这将比仅仅来回发布单一更新处理得更快。

这里主要的运算符是$unset删除现有字段和 $addToSet添加新的评估数组。两者都是通过循环文档中构成可能颜色的键并使用正则表达式过滤器排除您不想修改的其他键来构建的。

同时使用 $addToSet 和这一行:

    doc.colors = doc.colors || [];

目的是确保如果任何文档已经部分转换或以其他方式被已经开始存储正确数组的代码更改触及,那么这些不会受到更新过程的不利影响或覆盖。

关于MongoDB:列表中的几个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32802874/

相关文章:

linux - 连接到远程 MongoDB - SSH 问题

mongodb - 获取第一个聚合结果并在附加元素中聚合所有其他结果

javascript - 如何使用Mongoose使用MongoDB事务?

python - 如何使用批量操作更新mongodb中的文档?

node.js - MongoDB $lookup 对一个文档的对象数组进行查找

mongodb - 将大文件和数据导入 MongoDB 的内存有效方法?

android - 如何迁移解析导出的数据库?

node.js - 使用 Mongoose、Express 删除用户

node.js - 选择当月生日的所有用户

mongodb-query - mongodb中的分片问题