Обновите несколько записей в модели с помощью Waterline на Mongodb

Дан массив с объектами-книгами, где каждый status должен быть обновлен:

var books = [ 
              { id: '58b2e58', status: 'pending' },
              { id: '5903703', status: 'pending' } 
                ]

var status = {status: 'accepted'}

Я попробовал это:

Book.update(books, status).exec(function afterwards(err, updatedbooks) {
            if (err) {
                res.json(err)
                }
            console.log("updatedbooks:", updatedbooks);
});

но журнал обновленных книг пуст. При проверке в mongodb книги есть, я могу найти их с помощью Book.find(books);

Как упоминалось здесь, здесь это работает нормально, но я хочу, чтобы рядом с идентификатором также был статус=="ожидание" в ГДЕ критерии.


person Suisse    schedule 28.04.2017    source источник
comment
что вы имеете в виду под пустым? не могли бы вы предоставить журнал, пожалуйста?   -  person Ronin    schedule 28.04.2017
comment
Сэр, пожалуйста... console.log(updatedbooks:, updatedbooks); дает обновленные книги: [ ]   -  person Suisse    schedule 28.04.2017
comment
вы знаете, что эта операция не является идемпотентной, верно? может быть, вы запускали функцию раньше и уже изменили объекты в желаемое состояние, затем добавили console.log и снова запустили функцию, которая не соответствовала и, следовательно, ничего не обновляла? Это, очевидно, вернет любые объекты как часть параметра обратного вызова Sucessfully Updated Records. С счастливым шабатом!   -  person Ronin    schedule 28.04.2017
comment
Сэр, нет, это неправда. потому что console.log вызывается в функции, вызываемой after(), что означает, что после завершения обновления. братан, у тебя есть мануалы? С счастливым шабатом.   -  person Suisse    schedule 28.04.2017
comment
ДА, но если вы уже обновили все поля состояния своих книг, то при повторном запуске функции ничего не обновится.   -  person Ronin    schedule 28.04.2017
comment
Сэр, я больше не хочу называть вас сэром. На этом обсуждение заканчивается. Книги НЕ обновляются, примите это. Сэр.   -  person Suisse    schedule 28.04.2017


Ответы (2)


Пожалуйста, попробуйте это.

var bookId= ['1','3'];
var status = {status: 'accepted'}
Book.update({id:bookId, status: 'pending'}, status).exec(function afterwards(err, updatedbooks) {
        if (err) {
            console.log('error in update\n'+err);
            res.json(err)
            }
        else{
            console.log("updatedbooks:", updatedbooks);
        }
});

Это должно работать. Кроме того, если вы получаете ошибку, это даст вам представление о том, какую ошибку вы получаете.

person Foramkumar Parekh    schedule 25.09.2017
comment
Любая идея, как я могу обновить статус книги с идентификатором 1 до принятой и книги с идентификатором 3 до отклоненной? Я пробовал следующее, но обе записи обновляются со статусом принятого. var status = {status: ['принято', 'отклонено']} Book.update({id: bookId, status: 'ожидание'}, status).exec((ошибка, обновлено) => {}) - person 99darshan; 12.11.2017
comment
@99darshan Для обновления нескольких записей с разными значениями вы должны либо использовать базовый менеджер баз данных и его собственные методы, либо создать коллекцию Promise.all([])..., где каждое обещание представляет собой отдельную отправку Book.update(). В Sails нет метода пакетного обновления с разными значениями. - person nopuck4you; 08.08.2018
comment
для этого сначала используйте Book.find. Внутри этого выполните итерацию по данным, обновите необходимые данные с желаемыми значениями, а затем используйте метод data.save для обновления. Сохранить автоматически обновит содержимое. - person Foramkumar Parekh; 22.10.2018

Если у кого-то есть правильный ответ, не ждите. Я нашел обходной путь:

Функция find() может принимать такие критерии:

var bookCriteria = [ 
              { id: '1', status: 'pending' },
              { id: '3', status: 'pending' } 
                ]

Но функция update() работает только с массивом с идентификаторами:

var bookCriteria = [ '1','3']

Итак, давайте сначала найдем книги, соответствующие нашим критериям, а затем возьмем эти книги и обновим их.

      Book.find(bookCriteria).exec(function (err, booksFounded) {
            //booksFounded is an array with book objects, with status = 'pending'
            //but we need an array with booksFounded ids as strings

              var bookIDs = booksFounded.map( book => book.id}); //['1','3']

            //now update:

                Book.update(bookIDs , {status:'accepted'}).exec(function afterwards(err, updatedbooks) {
                if (err) {
                    res.json(err)
                    }
                console.log("updatedbooks:", updatedbooks);
                });

   })

У вас есть лучшее решение? В моем решении требуется 2 транзакции БД, но оно работает.

person Suisse    schedule 29.04.2017
comment
Здесь (var bookIDs = booksFounded.map( book => book.id});) вы можете использовать bookCriteria вместо booksFounded и избавиться от вызова find. Это работает для вас? - person Sangharsh; 01.05.2017
comment
Нет, потому что, как я уже писал, мне нужно обновить только те книги, у которых есть status:pending. Функция find() может принимать bookCriteria, а функция update() — нет. Вот почему вам сначала нужно «отфильтровать» книги, в которых есть эти ID + pending. И после этого обновить новые найденные книги, которые выполняют bookCriteria. - кто отрицает ответ, не имея лучшего ответа ?? - person Suisse; 01.05.2017