javascript - MongoDB - $set to update or push Array element -
in products collection, have array of recentviews has 2 fields viewedby & vieweddate.
in scenario if have record viewedby
, need update it. e.g if have array :-
"recentviews" : [ { "viewedby" : "abc", "vieweddate" : isodate("2014-05-08t04:12:47.907z") } ]
and user abc
, need update above & if there no record abc
have $push
.
i have tried $set
follows :-
db.products.update( { _id: objectid("536c55bf9c8fb24c21000095") }, { $set: { "recentviews": { viewedby: 'abc', vieweddate: isodate("2014-05-09t04:12:47.907z") } } } )
the above query erases other elements in array.
actually doing seems doing not singular operation, i'll walk through parts required in order or otherwise cover other possible situations.
what looking in part positional $
operator. need part of query "find" element of array want.
db.products.update( { "_id": objectid("536c55bf9c8fb24c21000095"), "recentviews.viewedby": "abc" }, { "$set": { "recentviews.$.vieweddate": isodate("2014-05-09t04:12:47.907z") } } )
so $
stands matched position in array update portion knows item in array update. can access individual fields of document in array or specify whole document update @ position.
db.products.update( { "_id": objectid("536c55bf9c8fb24c21000095"), "recentviews.viewedby": "abc" }, { "$set": { "recentviews.$": { "viewedby": "abc", "vieweddate": isodate("2014-05-09t04:12:47.907z") } } )
if fields not in fact change , want insert new array element if exact same 1 not exist, can use $addtoset
db.products.update( { "_id": objectid("536c55bf9c8fb24c21000095"), "recentviews.viewedby": "abc" }, { $addtoset:{ "recentviews": { "viewedby": "abc", "vieweddate": isodate("2014-05-09t04:12:47.907z") } } )
however if looking for "pushing" array singular key value if not exist need more manual handling, first seeing if element in array exists , making $push
statement not.
you mongoose methods in doing tracking number of documents affected update:
product.update( { "_id": objectid("536c55bf9c8fb24c21000095"), "recentviews.viewedby": "abc" }, { "$set": { "recentviews.$": { "viewedby": "abc", "vieweddate": isodate("2014-05-09t04:12:47.907z") } }, function(err,numaffected) { if (numaffected == 0) { // document not updated can push onto array product.update( { "_id": objectid("536c55bf9c8fb24c21000095") }, { "$push": { "recentviews": { "viewedby": "abc", "vieweddate": isodate("2014-05-09t04:12:47.907z") } } }, function(err,numaffected) { } ); } } );
the word of caution here there bit of implementation change in writeconcern messages mongodb 2.6 earlier versions. being unsure right how mongoose api implements return of numaffected
argument in callback difference mean something.
in prior versions, if data sent in initial update matched existing element , there no real change required "modified" amount returned 1
though nothing updated.
from mongodb 2.6 write concern response contains 2 parts. 1 part shows modified document , other shows match. while match returned query portion matching existing element, actual modified document count return 0
if in fact there no change required.
so depending on how return number implemented in mongoose, might safer use $addtoset
operator on inner update make sure if reason 0 affected documents not exact element existed.
Comments
Post a Comment