Обновление документа MongoDB от двух разных клиентов с использованием собственного драйвера nodejs - PullRequest
0 голосов
/ 10 июня 2019

У меня есть collection пользователей, которых я хотел бы регулярно обновлять, используя несколько различных 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 голосов
/ 10 июня 2019

вы должны найти пользователей после обновления первого курсора, например:

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);
}
...