MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Campos de cálculo automático no mongodb


O MongoDB não pode fazer o que você está pedindo com 1 consulta. Mas você pode fazer isso em uma consulta de duas etapas.

Em primeiro lugar, insira o novo valor no array:
db.Test3.findOneAndUpdate(
{_id: ObjectId("58047d0cd63cf401292fe0ad")},
{$push: {"items":  {"date": ISODate("2013-01-27T16:38:16.163+0000")}}},
{returnNewDocument: true},
function (err, result) {

}
);

em seguida, atualize "lastDate" somente se for menor que o último Pushed.
  db.Test3.findOneAndUpdate (
   {_id: ObjectId("58047d0cd63cf401292fe0ad"), "lastDate":{$lt: ISODate("2013-01-25T16:38:16.163+0000")}},
   {$set: {"lastDate": ISODate("2013-01-25T16:38:16.163+0000")}},
   {returnNewDocument: true},
   function (err, result) {
   }
  ); 

o segundo parâmetro "lastDate" é necessário para evitar a condição de corrida. Dessa forma, você pode ter certeza de que dentro de "lastDate" há com certeza a "data mais alta enviada".

Relacionado ao segundo problema que você está perguntando, você pode seguir uma estratégia semelhante. Atualizar {"allAre": false} somente se {"_id":yourID, "items.is":false)} . Basicamente defina "false" apenas se algum filho de tiver um valor 'false'. Se você não encontrou um documento com essa propriedade, não atualize nada.
// add a new Child to false
db.Test4.findOneAndUpdate(
{_id: ObjectId("5804813ed63cf401292fe0b0")},
{$push: {"items":  {"is": false}}},
{returnNewDocument: true},
 function (err, result) {

}
);

// update allAre to false if some child is false
db.Test4.findOneAndUpdate (
   {_id: ObjectId("5804813ed63cf401292fe0b0"), "items.is": false},
   {$set: {"allAre": false}},
   {returnNewDocument: true},
   function (err, result) {
   }
  );