I need to update all documents from a collections but differnt value as per condition using MongoDB. Here is my collection:
db_users:
{ "_id" : ObjectId("4e93037bbf6f1dd3a0a9541a"), "device_type" : "Android" },
{ "_id" : ObjectId("4e93037bbf6f1dd3a0a9541b"), "device_type" : " " }
Here I need to add one extra column (i.e-version) for each document and also update version=1.0 when "device_type" : "Android" and version='' when "device_type" : " ".
I need query for this.
I think there can't be a single query to do two type of operation but there could be two queries
db.db_users.update({'device_type':"Android"},{$set : {'version':"1.0"}},{multi:true});
db.db_users.update({'device_type':""},{$set : {'version':""}},{multi:true});
also in the document it shows a blank space " ", whereas in question you mentioned it "". if it's not consistent you should user $or.
It can also be done through a single script
db.db_users.find().forEach(function(doc){if(doc.device_type && doc.device_type==='Android'){doc.version="1.0"}else{doc.version=""} db.db_users.save(doc)});
if there are multiple logic, it's better to go for script, if it's just limited as you mentioned in your question two updates would be preferable.
For MongoDB 3.4 and newer:
Using the aggregation framework, the $addFields and $out pipeline would update your collection with a single aggregate operation. For example:
db.users.aggregate([
{
"$addFields": {
"version": {
"$switch": {
"branches": [
{ "case": { "$eq": ["$device_type", "Android"] }, "then": "1.0" },
{ "case": { "$eq": ["$device_type", " "] }, "then": "" }
]
}
}
}
},
{ "$out": "users" }
])
For MongoDB 3.2:
You could utilise the bulkWrite methods for faster and more efficient updates. Consider the following operation:
var ops = [];
db.users.aggregate([
{
"$project": {
"version": {
"$cond": [
{ "$eq": ["$device_type", "Android"] },
"1.0",
""
]
}
}
}
]).forEach(function(doc){
ops.push( {
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "version": doc.version } }
}
});
if (ops.length === 500) {
// Execute per 500 operations and re-initialise
db.users.bulkWrite(ops);
ops = [];
}
})
if (ops.length > 0) {
db.users.bulkWrite(ops);
}
For MongoDB <= 3.0 and >= 2.6:
var bulk = db.users.initializeUnorderedBulkOp();
var count = 0;
db.users.aggregate([
{
"$project": {
"version": {
"$cond": [
{ "$eq": ["$device_type", "Android"] },
"1.0",
""
]
}
}
}
]).forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne({ "$set": { "version": doc.version } });
count++;
if (count % 500 === 0) {
// Excecute per 500 operations and re-initialise
bulk.execute();
bulk = db.users.initializeUnorderedBulkOp();
}
})
// clean up remaining operations in queue
if (count > 0) {
bulk.execute();
}