2016-04-01 2 views
2

Как для перебора массив объектов, чтобы обновить документы с MongoDB и сохранить измененные документы, чтобы вернуться назад в ответобновление нескольких документов с MongoDB

Обратите внимание на комментарии в коде

.put(function (req, res) { 

    var data = req.body.data; 
    var documents = []; 
    for (var item in data) { 

     var id = data[item]._id; 
     var document = data[item]; 

     Item.update({ _id: id }, document, { overwrite: true }, function (err, item) { 
      if (err) { 
      res.send({'error':'Error'}); 
      } 
      Item.findById(id, function (err, document) { 
      if (err) { 
       res.send({}); 
      } 
      documents.push(document); // documents are pushed 
      }); 

     });   
    } 
    documents ; // value is [] 
    res.json({ 
     items: documents 
    });   
}) 

ответ

2

Используйте Promise.all() и .findByIdAndUpdate() вместо этого. Пока ваша окружающая среда поддерживает ES6 contructs, или импортировать что-то, что обеспечивает Promise.all():

Promise.all(
    req.body.data.map(function(doc) { 
     var id = doc._id; 
     delete doc._id; 
     return Item.findByIdAndUpdate(id,doc,{ "new": true }); 
    }) 
).then(function(documents) { 
    res.json({ "items": documents }) 
}); 

Нет необходимости использования внешних библиотек.

+0

это кажется лучшим решением, но «return Item.findByIdAnUpdate (id, doc, {" new ": true});" бросает исключение: «Ошибка типа не является функцией», вместо этого я меняю его на «return {test:« test »}» и отлично работает. –

+0

@Jordi «typo» '.findByIdAndUpdate()', а не '.findByIdAnUpdate()', в котором отсутствует '' d ''in' "And" '. Все точки «были» и «есть», что вам обоим не нужен дополнительный импорт, а во-вторых, '.findByIdAndUpdate()' лучше, чем отдельные операции '.update()' и '.findById()'. Не только две поездки на сервер вместо одного, но и не «действительно» документ в состоянии непосредственно после внесения изменений. Другие операции могут быть изменены в двух вариантах. Но это не относится к любому из '.find ** AndUpdate()' varaints. –

+0

Да, была ошибка «опечатки», извините и спасибо @BlakesSeven. –

1

Поскольку update является асинхронным, ваш documents пуст и немедленно возвращается. Создавайте обещания для каждого обновления. Также создайте внешний массив обещаний. Надавите эти обещания на этот массив и отправьте ответ, когда все будет сделано. Я использую Q library

.put(function (req, res) { 

    var data = req.body.data; 
    var documents = []; 
    var promises = [] 
    for (var item in data) { 

     var id = data[item]._id; 
     var document = data[item]; 
     var itemDefer = Q.defer(); 

     Item.update({ _id: id }, document, { overwrite: true }, function (err, item) { 
      if (err) { 
      res.send({'error':'Error'}); 
      } 
      Item.findById(id, function (err, document) { 
      if (err) { 
       itemDefer.reject(err); 
      } 
      itemDefer.resolve(document); 
      }); 
     }); 
     promises.push(itemDefer.promise);  
    } 
    Q.all(promises).then(function(documents) { 
     res.json({items: documents});  
    }, then(function(err) { 
     res.send({}) 
    })) 

})