使用Node.js本机驱动程序从两个不同的客户端更新MongoDB文档

时间:2019-06-10 13:07:08

标签: javascript mongodb nodes node-mongodb-native

我有collection个用户,我想使用几种不同的API(每个API都有自己的速率限制等)来定期更新。

所以我有一些具有以下类似结构的cron作业:

const cursor_i = db.collection('users').find();

while(await cursor_i.hasNext()){

    let user = await cursor_i.next();

    user.field_1 = 'Some New Stuff';

    const write_result = await db.collection('newusers').save(user);
    if(!write_result.result.ok){
        console.log(write_result);
    }
}

问题在于,当一个文档由多个更新程序同时更新时,只有最后一个save()调用才有意义。

为澄清起见,请考虑以下代码:

const cursor_1 = db.collection('users').find();
const cursor_2 = db.collection('users').find();

let user_cursor_1 = await cursor_1.next(); // user_cursor_1 has the first user in the collection
let user_cursor_2 = await cursor_2.next(); // user_cursor_2 has the first user in the collection

user_cursor_1.new_field_1 = 'ok';
const write_result = await db.collection('users').save(user_cursor_1);
if(!write_result.result.ok){
    console.log(write_result);
}

// first user in collection now has a new field named new_field_1 with the value 'ok'

user_cursor_2.new_field_2 = 'ok';
const write_result_2 = await db.collection('newusers').save(user_cursor_2);
if(!write_result_2.result.ok){
    console.log(write_result);
}

// first user in collection now has a new field named new_field_2 with the value 'ok' but DOES NOT have new_field_1 anymore

因此,集合中的第一个用户已被更新两次,但最终只会具有第二个更新的作用。

我可以想到一些通过自己实现锁来避免这种情况的方法,但是我想MongoDB必须有一些东西来处理这些情况。

1 个答案:

答案 0 :(得分:0)

您应该在更新第一个游标后找到用户,例如:

const cursor_1 = db.collection("users").find();
let user_cursor_1 = await cursor_1.next(); // user_cursor_1 has the first user in the collection

user_cursor_1.new_field_1 = "ok";
const write_result = await db.collection("users").save(user_cursor_1);
if (!write_result.result.ok) {
  console.log(write_result);
}


const cursor_2 = db.collection("users").find();
let user_cursor_2 = await cursor_2.next(); // user_cursor_2 has the first user in the collection

user_cursor_2.new_field_2 = "ok";
const write_result_2 = await db.collection("newusers").save(user_cursor_2);
if (!write_result_2.result.ok) {
  console.log(write_result);
}