MongoDB non può fare ciò che stai chiedendo con 1 query. Ma puoi farlo in una query in due passaggi.
Prima di tutto, inserisci il nuovo valore nell'array:
db.Test3.findOneAndUpdate(
{_id: ObjectId("58047d0cd63cf401292fe0ad")},
{$push: {"items": {"date": ISODate("2013-01-27T16:38:16.163+0000")}}},
{returnNewDocument: true},
function (err, result) {
}
);
quindi aggiorna "lastDate" solo se è inferiore all'ultimo 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) {
}
);
il secondo parametro "lastDate" è necessario per evitare race condition. In questo modo puoi essere sicuro che all'interno di "lastDate" ci sono sicuramente le "data più alta spinta".
In relazione al secondo problema che stai chiedendo puoi seguire una strategia simile. Aggiorna {"allAre": false}
solo se {"_id":yourID, "items.is":false)}
. Fondamentalmente imposta "false" solo se qualche figlio di ha un valore "falso". Se non hai trovato un documento con questa proprietà, non aggiornare nulla.
// 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) {
}
);