如何使用节点js更新mongo集合中所有文档的_id?

问题描述 投票:1回答:1

我需要更新所有文档的ID值。我知道如何仅更新集合的一个文档。但是如何更新所有文档?

db name - mydb
collection name - customers
documents - many....

/* 1 */
{
    "_id" : ObjectId("5e1d814ac488402bcf1600b3"),
    "name" : "Company Inc",
    "address" : "Highway 37"
}

/* 2 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328384"),
    "name" : "Company Inc 10",
    "address" : "Highway 37"
}

/* 3 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328385"),
    "name" : "Company Inc 11",
    "address" : "Highway 37"
}

/* 4 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328386"),
    "name" : "Company Inc 12",
    "address" : "Highway 37"
}

/* 5 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328387"),
    "name" : "Company Inc 13",
    "address" : "Highway 37"
}
etc.,

这里我只想更新所有文档中的_id值。对于每个文档,我需要更新id作为数组中给定的输入。我只是简单地尝试将i++作为值传递。它不起作用。

var mongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";

mongoClient.connect(url, function(err, db) {
  if (err) throw err;
  var dbo = db.db("mydb");
  var collection = dbo.collection("customers");
  var customers = collection.find().toArray();
  var bulkArray = [];
  customers.forEach(function* (d, i) {
    bulkArray.push({ updateOne: { filter: { _id: mongodb.ObjectID(d._id) }, 
        update: { $set: { _id:  i++ }}, upsert:true }});
  });
 collection.bulkWrite(bulkArray, {ordered:true, w:1});
});
node.js mongodb
1个回答
0
投票

您可以尝试这个:

db.customers.aggregate([{ $group: { _id: '', data: { $push: '$$ROOT' } } }, {
    $project: {
        data: {
            $map:
            {
                input: "$data",
                as: "each",
                in: { $mergeObjects: ['$$each', { '_id': { $indexOfArray: ['$data', '$$each'] } }] }
            }
        }
    }
}, { $unwind: '$data' }, { $replaceRoot: { newRoot: '$data' } }, { $out: "customersNew" }])

来自客户的收集数据:

/* 1 */
{
    "_id" : ObjectId("5e1d814ac488402bcf1600b3"),
    "name" : "Company Inc",
    "address" : "Highway 37"
}

/* 2 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328384"),
    "name" : "Company Inc 10",
    "address" : "Highway 37"
}

/* 3 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328385"),
    "name" : "Company Inc 11",
    "address" : "Highway 37"
}

/* 4 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328386"),
    "name" : "Company Inc 12",
    "address" : "Highway 37"
}

/* 5 */
{
    "_id" : ObjectId("5e1d9176bd5be834bf328387"),
    "name" : "Company Inc 13",
    "address" : "Highway 37"
}

结果写给客户新收藏:

/* 1 */
{
    "_id" : 0,
    "name" : "Company Inc",
    "address" : "Highway 37"
}

/* 2 */
{
    "_id" : 1,
    "name" : "Company Inc 10",
    "address" : "Highway 37"
}

/* 3 */
{
    "_id" : 2,
    "name" : "Company Inc 11",
    "address" : "Highway 37"
}

/* 4 */
{
    "_id" : 3,
    "name" : "Company Inc 12",
    "address" : "Highway 37"
}

/* 5 */
{
    "_id" : 4,
    "name" : "Company Inc 13",
    "address" : "Highway 37"
}

不确定是否需要这样做。

  1. 除非您否则,否则您将无法更新现有文档的_id删除该文档并用新的必需_id插入。

  2. 而不是从数据库读取所有文档,而是删除并重写所有返回集合将是对数据库的两三种调用如此大量的数据也可能令人担忧。

  3. 您可以尝试执行此查询,但是在最后阶段$out-请谨慎处理-会将聚合输出写入指定的集合名称(不指定现有集合的名称-除非需要/测试)!您可以通过删除$out阶段来验证正在写入的数据,然后使用$out将数据写入新集合,一旦您满意新数据集合删除旧的并重命名新的(customersNew)到customers

  4. 如果此聚合无法达到内存限制,则可能需要使用allowDiskUse: trueaggregate
© www.soinside.com 2019 - 2024. All rights reserved.