The matching element looks like that:
{
"_id": {
"$oid": "519ebd1cef1fce06f90e3157"
},
"from": "Tester2",
"to": "Tester",
"messages": [
{
"username": "Tester2",
"message": "heeey",
"read": false
},
{
"username": "Tester",
"message": "hi!",
"read": false
},
{
"username": "Tester2",
"message": "test",
"read": false
}
],
}
Now I try to set the read
property to the current date just of the subelements where the username is not equal to Tester
:
var messages = db.collection('messages');
messages.update(
{
_id: new BSON.ObjectID("519ebd1cef1fce06f90e3157"),
messages: {
$elemMatch: { username: { $ne: "Tester" } }
}
},
{ $set: { 'messages.$.read': new Date() } },
{ multi: true }, function(error, result) {
console.log(error);
console.log(result);
});
But just the first messages subelement read
property updates:
{
"_id": {
"$oid": "519ebd1cef1fce06f90e3157"
},
"from": "Tester2",
"to": "Tester",
"messages": [
{
"username": "Tester2",
"message": "heeey",
"read": {
"$date": "2013-01-01T00:00:00.000Z"
}
},
{
"username": "Tester",
"message": "hi!",
"read": false
},
{
"username": "Tester2",
"message": "test",
"read": false
}
],
}
What's wrong with the code? I'm using node.js v0.10.8 and MongoDB v2.4.3 together with node-mongodb-native.
There's nothing wrong with your code; the $
operator contains the index of the first matching array element. The {multi: true}
option only makes the update
apply to multiple documents, not array elements. To update multiple array elements in a single update
you must specify them by numeric index.
So you'd have to do something like this:
messages.update(
{
_id: new BSON.ObjectID("519ebd1cef1fce06f90e3157")
},
{ $set: {
'messages.0.read': new Date(),
'messages.2.read': new Date()
} },
function (err, result) { ... }
);