javascript - how to update an array inside a MongoDB collection with another array but update only changed values? -
having following collection named eshops:
{ "_id" : objectid("53e87e239ae974e6a0a81004"), "name" : "www.example.com", "products" : [ { "name" : "apple", //lets name key here primary key of products "status" : 0 }, { "name" : "banana", "status" : 0 }, { "name" : "iphone", "status" : 0 } ] }
and having array
var products = [ {name: "apple", status: 1} {name: "notebook", status: 0} ]
what should update query if wanted following result?
{ "_id" : objectid("53e87e239ae974e6a0a81004"), "name" : "www.example.com", "products" : [ { "name" : "apple", "status" : 1 }, { "name" : "banana", "status" : 0 }, { "name" : "iphone", "status" : 0 }, { "name" : "notebook", "status" : 0 } ] }
the full explaination of @ end read on.
that cannot cannot done "atomically" in single operation , best "bulk" operations best way it.
var products = [ {name: "apple", status: 1} {name: "notebook", status: 0} ]; var bulk = db.collection.initializeorderedbulkop(); products.foreach(function(product) { // try update bulk.find({ "_id" : objectid("53e87e239ae974e6a0a81004"), "products.name": product.name }) .updateone({ "$set": { "products.$.status": product.status } }); // try "push" bulk.find({ "_id" : objectid("53e87e239ae974e6a0a81004"), "products.name": { "$ne": product.name } }) .updateone({ "$push": { "products": product } }); }); bulk.execute();
the other alternative retrieve document via .findone()
or similar operation, alter array content in client code , .save()
altered content back.
that don't want since there no guarantee document has not "changed" since read memory. , if other members added array sort of action "overwrite" them.
so loop items multiple updates. @ least "bulk" operations send these @ once server without waiting responses individual writes.
but point out. if value still same? need @ "writeresult" response "bulk" operation on .execute()
:
writeresult({ "nmatched" : 2, "nupserted" : 0, "nmodified" : 2 })
so there 2 (2) actions here depite 4 (4) operations being sent in total. if array contained 1 more item, "iphone" without changes:
var products = [ {name: "apple", status: 1} {name: "notebook", status: 0}, {name: "iphone", status: 0 } ];
then response this:
writeresult({ "nmatched" : 3, "nupserted" : 0, "nmodified" : 2 })
since "bulk" api smart enough see value "status" on matching "iphone" not different value present ( assuming nothing else changed in between ) , not report modification.
so let server work, because smarts code there.
Comments
Post a Comment