【问题标题】:How update MongoDb documents inside a for loop如何在 for 循环中更新 MongoDb 文档
【发布时间】:2020-03-17 16:45:25
【问题描述】:

我有一个对象数组

df =[{user: "name1", newdata: "data1"},
     {user: "name2", newdata: "data3"},
     ....
]

我有一个包含 userkey1 字段的集合。我想找到用户并用dato.newdata 更新'key1'。我试图包含在一个 for 循环中,但它不起作用。这是我的代码:

const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';

client.connect(function(error){
    for (dato of df){
        client.db(dbasename).collection(collectionname).updateOne(
            {user: dato.user},
            {$set: {key1: dato.newdata}},
            function(error,result){
                if (error) console.log(error);
                if (result) {
                    console.log(JSON.stringify(result));
                }
            }
        );  
    }
})

附加信息:我注意到它适用于找到的第一个用户。也许updateOne 返回了一个承诺,而我没有正确管理它?

我已经按照你们中的一些人的建议尝试了其他代码。但它不起作用。:

const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';

async function changeValue (dbasename,collectionname, user, newData) {
  client.db(dbasename).collection(collectionname).updateOne(
      {user: user},
      {$set: {key1: newdata}},
      {upsert:false},
      {multi:false},
      function(error,result){
        if (error) console.log(error);
        if (result) {
            console.log(JSON.stringify(result));
        }
    }
  );
}

client.connect(function(error){
  for (dato of df){
     await changeValue(dbasename,collectionname, dato.user, dato.newdata);
  }
})

编译器说:SyntaxError: await is only valid in async function

【问题讨论】:

  • 我想{ $set: { newdata: dato.newdata } } 而不是 { $set: { key1: dato.newdata } },如果你想更新newdata字段。
  • 不,我想用dato.newdata 更新key1 字段。我已经更新了我的问题以避免混淆。

标签: arrays node.js mongodb


【解决方案1】:

由于 MongoDB 操作是异步的,因此 for 循环不会在迭代期间等待插入/更新文档等操作。

因此,您必须将 forEach 与 await 结合使用,以确保在进行下一次迭代之前更新文档。

async changeValue(user, newData) {
        db.collectionName.updateOne(
            {user: user},
            {$set: {key1: newdata}},
            {upsert:false},
            {multi:false}
        );
    }
      df.forEach(function(item){
       await changeValue(item.user,item.newData);
    });

【讨论】:

  • 如果你能详细说明你的答案而不仅仅是显示正确的代码,那会让你的答案更好。
  • 我创建了一个带参数的异步函数。在该函数中,我使用数据库对象(db)和集合名称调用了更新方法。更新方法的第一个参数是选择标准,第二个参数是设置您要设置的新值,第三个参数是 upsert,这意味着如果it true than it will create new document when selection criteria is not matched other wise it will update the document.By setting the multi true it will update multiple document is selection criteria is matched.
  • 如果您可以通过编辑将其直接添加到您的答案中,那么每个人都可以立即看到它,并且您的答案更易于阅读。
  • 它不起作用。我声明async function changeValueawait changeValue 有错误。错误信息是:SyntaxError: await is only valid in async function
【解决方案2】:

最后,这段代码可以工作了。

    async function changeValue(dbasename, collectionname, dato){
        let client = await MongoClient.connect(url).catch(error => {console.log(error)});
        if (!client) {return;};
        let db = client.db(dbasename);
        let collection = db.collection(collectionname);
        collection.updateOne(
            {user: dato.user},
            {$set: {key1: dato.newdata}},
            function(error,result){
                    if (error) console.log(error);
                    if (result.result.n === 0) {
                            console.log(dato.user); //print not found users
                    }
            }
        );
        await client.close();
    };  

    for (dato of df){
        changeValue(dbasename, collectionname, dato);
    } 

【讨论】:

    【解决方案3】:

    MongoDB 调用是异步的,但到目前为止,循环完成了所有迭代并且不等待操作结束。

    我认为你可以这样做,

    async changeValue(user, newData) {
        client.db(dbasename).collection(collectionname).updateOne(
            {user: user},
            {$set: {key1: newdata}},
            function(error,result){
                if (error) console.log(error);
                if (result) {
                    console.log(JSON.stringify(result));
                }
            }
        );
    }
    
    for (dato of df){
        await changeValue(dato.user, dato.newdata);
    }
    

    这只是一个粗略的想法,您可能需要为此做一些更改。但我认为这可能有助于了解需要做什么。

    【讨论】:

    • @chandukomati 怎么样?请解释一下。
    • @chandukomati 您删除了您的评论,但忘记删除反对票。如果有什么要补充的,请随时发表评论或发布新答案。
    • 它不起作用。我声明async function changeValueawait changeValue 有错误。错误信息是:SyntaxError: await is only valid in async function
    • @Juan 你需要创建函数(在其中你有你的 for 循环)async
    • @gprathour,我尝试进行异步,但失败了。请检查我在问题中添加的新代码。
    猜你喜欢
    • 2021-05-31
    • 2021-11-12
    • 1970-01-01
    • 2015-05-14
    • 2023-03-19
    • 2012-10-08
    • 2020-09-08
    • 1970-01-01
    • 2017-08-15
    相关资源
    最近更新 更多