mongodb - Adding values at front with $addToSet modifier -
i trying run update query on mongo, add few values in existing array property.
my goal add elements @ beginning of array, instead of @ end, happening default. here code using:
db.collection("project").update({'_id': group.project}, {$addtoset: {'endpointorder': {$each: group.endpointorder, $position: 0}}}, {multi: true}) as can see above, if change 'addtoset' use 'push' modifier, works fine, keep duplicates, can't be. so, assumption that, $position supported '$push' , not '$addtoset'.
any idea/suggestions how can achieve that? thanks.
the $addtoset operator produces "set" of "unique" items after. unfortunately there common mantra through mongodb , other "set operators":
"sets not considered ordered"
so when add items "set" ( or combine other operations ) there no guarantee items appears in position whether beginning or end of "set". official line element appear in order, , not matter long part of "set".
but there way around this, , means not use $addtoset instead use other filtering logic in combination $push:
consider document:
{ "a": [ 3,1,2 ] } so if wanted add new element 4 list , prepend @ "first" position element not part of "set", construct query , update this:
db.collection.update( { "a": { "$ne": 4 } }, { "$push": { "a": { "$each": [4], "$position": 0 } } } ) in brief: "don't push array if value present in array."
and there it. if asked add element present of course query condition false , nothing modified.
in end same results $addtoset operation, except have complete control on element positioning or "sorting" required. need check matching element before deciding whether change anything.
a procedure handling multiple elements should using "bulk" operations api efficiency
var items = [4,3]; var bulk = db.collection.initializeorderedbulkop(); bulk.find({ "a": { "$nin": items } }).updateone( { "$push": { "a": { "$each": items, "$position": 0 } } } ); items.foreach(function(item) { bulk.find({ "a": { "$ne": item } }).updateone( { "$push": { "a": { "$each": [item], "$position": 0 } } } ); }); bulk.execute(); which result in 1 of update operations within loop matching or modifying anything:
{ "a": [ 4,3,1,2 ] } or values not exist @ all:
var items = [5,8]; var bulk = db.collection.initializeorderedbulkop(); bulk.find({ "a": { "$nin": items } }).updateone( { "$push": { "a": { "$each": items, "$position": 0 } } } ); items.foreach(function(item) { bulk.find({ "a": { "$ne": item } }).updateone( { "$push": { "a": { "$each": [item], "$position": 0 } } } ); }); bulk.execute(); then first operation modify , looped instructions not match since items there.
{ "a": [ 5,8,4,3,1,2 ] }
Comments
Post a Comment