I\'m a MongoDB newbie and wanted to ask how to write an update command involving upsert and list.
Basically I want to accomplish something like this:
EDITED TO INCLUDE CORRECT SOLUTION
This is exactly the problem I hit learning Mongo - you're looking for the $addToSet operator (see docs here) that's used with the update command, in conjunction with the $ positional operator you were using.
$addToSet
{ $addToSet : { field : value } }
Adds value to the array only if its not in the array already.
The query thus becomes (db.stack is the collection I used for testing purposes), sample run to follow:
db.stack.update({ "trips.name":"2010-05-10" },
{ $addToSet: { "trips.$.loc":{"lat":11, "lng":12} } }
);
TEST RUN (with some abbreviations for space of the elements that aren't important):
#### YOUR ITEM IN THE DB
> db.stack.find({"trips.name":"2010-05-10"})
{ "_id" : ObjectId("4c28f62cbf8544c60506f11d"), "some_other_data" : "goes here",
"trips" : [
{ "name" : "2010-05-10",
"loc" : [ {
"lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:35"
}, { "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:24"
} ] },
{ "name" : "2010-05-08",
"loc" : [ ... ]
} ] }
#### SUCCESSFULLY ADDS ITEM TO PROPER ARRAY
> db.stack.update({"trips.name":"2010-05-10"}, {$addToSet: {"trips.$.loc":{"lat":11, "lng":11}}});
> db.stack.findOne()
{ "_id" : ObjectId("4c28f62cbf8544c60506f11d"), "some_other_data" : "goes here",
"trips" : [
{ "loc" : [
{ "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:35"
}, { "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:24"
}, { "lat" : 11,
"lng" : 11
}
], "name" : "2010-05-10"
},
{ "name" : "2010-05-08",
"loc" : [ ... ]
} ] }
#### ON REPEAT RUN DOESN'T ADD NEW ELEMENT
> db.stack.update({"trips.name":"2010-05-10"}, {$addToSet: {"trips.$.loc":{"lat":11, "lng":11}}});
> db.stack.findOne()
{ "_id" : ObjectId("4c28f62cbf8544c60506f11d"), "some_other_data" : "goes here",
"trips" : [ {
"loc" : [
{ "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:35"
}, { "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:24"
}, { "lat" : 11,
"lng" : 11
}
], "name" : "2010-05-10"
},
{ "name" : "2010-05-08",
"loc" : [ ... ]
} ] }
#### BUT WILL CORRECTLY ADD ANOTHER ELEMENT TO THE SAME ARRAY IF IT'S NOT PRESENT
> db.stack.update({"trips.name":"2010-05-10"}, {$addToSet: {"trips.$.loc":{"lat":11, "lng":12}}});
> db.stack.findOne()
{ "_id" : ObjectId("4c28f62cbf8544c60506f11d"), "some_other_data" : "goes here",
"trips" : [
{ "loc" : [
{ "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:35"
}, { "lat" : 21.321231,
"lng" : 16.8783234,
"updated_at" : "Mon May 10 2010 15:24:24"
}, { "lat" : 11,
"lng" : 11
}, { "lat" : 11,
"lng" : 12
}
], "name" : "2010-05-10"
},
{ "name" : "2010-05-08",
"loc" : [ ... ]
} ] }