/ insert

NodeJS - Bulk update to MongoDB using mongoose

Was trying to do bulk update to MongoDB using mongoose + Node JS. Struggled a bit on this one because of a silly mistake. Thought to share it here.

Software Versions

Mongoose4.3.6
MongoDb3.2
## Requirement

I had a collection of articles and requirement was to do a bulk update of published field based on action from Admin.

var ArticleSchema = new Schema({
	type: {
		type: String,
		required: true
	},
	title: {
		type: String,
		required: true
	},
	content: {
		type: String,
		required: true
	},
	published: {
		type: Boolean,
		default: false
	},
	created_at: {
		type: Date,
		default: Date.now
	},
	updated_at: {
		type: Date,
		default: Date.now
	}
});

From NodeJS code:

var mongoose = require('mongoose'); /*List of id strings*/

var ids = req.body.ids;
var bulk = Article.collection.initializeOrderedBulkOp();

for (var i = 0; i < ids.length; i++) {
	var id = ids[i];
	bulk.find({
		'_id': mongoose.Types.ObjectId(id)
	}).updateOne({
		$set: {
			published: true
		}
	});
}

I was getting a list of ids as string from the webpage and I was not converting it to ObjectId before using it in the find query. Using mongoose.Types.ObjectId(id)fixed the issue.

Result

{
	"ok": 1,
	"writeErrors": [],
	"writeConcernErrors": [],
	"insertedIds": [],
	"nInserted": 0,
	"nUpserted": 0,
	"nMatched": 2,
	"nModified": 2,
	"nRemoved": 0,
	"upserted": []
}

In this case, find query matched 2 resultds and updated 2 of them with published as true as can be seen from nMatched and nModified.

Generic Template

var bulk = < collectionName > .collection.initializeOrderedBulkOp();
bulk.find(query).updateOne(update);
bulk.execute(function(error, result) {});

Examples

var bulk = Article.collection.initializeOrderedBulkOp(); //ordered
var bulk = Article.collection.initializeUnorderedBulkOp(); //unordered
bulk.find({
	'_id': Article.getObjectId(id)
}).updateOne({
	$set: {
		published: true
	}
}); //Updates one bulk.
find({
	'a': 1
}).update({
	$set: {
		published: true
	}
}); //Update all documents
bulk.find({
	'_id': Article.getObjectId(id)
}).upsert().updateOne({
	$set: {
		published: true
	}
}); //Insert new doc if not found bulk.
find({
	'_id': Article.getObjectId(id)
}).remove(); //Remove the document

References

http://blog.mongodb.org/post/84922794768/mongodbs-new-bulk-api