Monday, 14 June 2021

MongoDB: Ordered and unordered inserts

By default, MongoDB perform ordered inserts. Usually executing an ordered insert is slower than executing an unordered insert.

 

Ordered operations stop after an error, while unordered operations continue to process any remaining write operations in the queue.

 

Let’s see it with an example.

> db.countries.insertMany([{_id : "India", name : "India"}, {_id : "Japan", name : "Japan"}, {_id : "Iran", name : "Iran"}])
{
	"acknowledged" : true,
	"insertedIds" : [
		"India",
		"Japan",
		"Iran"
	]
}

As you see above snippet, I inserted three country names into countries collection.

 

Let’s fetch all the inserted documents.

> db.countries.find()
{ "_id" : "India", "name" : "India" }
{ "_id" : "Japan", "name" : "Japan" }
{ "_id" : "Iran", "name" : "Iran" }


Let’s insert following documents into countries collection.

[{
	_id: "China",
	name: "China"
}, {
	_id: "Japan",
	name: "Japan"
}, {
	_id: "Italy",
	name: "Italy"
}]


As you see above snippet, I am trying to insert the Japan country detail again, which leads to conflict.

> db.countries.insertMany([{_id : "China", name : "China"}, {_id : "Japan", name : "Japan"}, {_id : "Italy", name : "Italy"}])
uncaught exception: BulkWriteError({
	"writeErrors" : [
		{
			"index" : 1,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: sample.countries index: _id_ dup key: { _id: \"Japan\" }",
			"op" : {
				"_id" : "Japan",
				"name" : "Japan"
			}
		}
	],
	"writeConcernErrors" : [ ],
	"nInserted" : 1,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
}) :
BulkWriteError({
	"writeErrors" : [
		{
			"index" : 1,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: sample.countries index: _id_ dup key: { _id: \"Japan\" }",
			"op" : {
				"_id" : "Japan",
				"name" : "Japan"
			}
		}
	],
	"writeConcernErrors" : [ ],
	"nInserted" : 1,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})
BulkWriteError@src/mongo/shell/bulk_api.js:367:48
BulkWriteResult/this.toError@src/mongo/shell/bulk_api.js:332:24
Bulk/this.execute@src/mongo/shell/bulk_api.js:1186:23
DBCollection.prototype.insertMany@src/mongo/shell/crud_api.js:326:5
@(shell):1:1

As per ordered inserts behavior, it stops inserting after an error, but all the documents that are inserted before error are still persisted to database.

> db.countries.find()
{ "_id" : "India", "name" : "India" }
{ "_id" : "Japan", "name" : "Japan" }
{ "_id" : "Iran", "name" : "Iran" }
{ "_id" : "China", "name" : "China" }


How can I skip the documents that cause error and proceed with other documents?

Use unordered inserts functionality. Unordered operations continue to process any remaining write operations in the queue.

 

You can enable unordered inserts by setting the property ‘order’ to false.

db.countries.insertMany([{_id : "China", name : "China"}, {_id : "Japan", name : "Japan"}, {_id : "Italy", name : "Italy"}], {ordered: false})


Let’s execute above snippet.

> db.countries.insertMany([{_id : "China", name : "China"}, {_id : "Japan", name : "Japan"}, {_id : "Italy", name : "Italy"}], {ordered: false})
uncaught exception: BulkWriteError({
	"writeErrors" : [
		{
			"index" : 0,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: sample.countries index: _id_ dup key: { _id: \"China\" }",
			"op" : {
				"_id" : "China",
				"name" : "China"
			}
		},
		{
			"index" : 1,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: sample.countries index: _id_ dup key: { _id: \"Japan\" }",
			"op" : {
				"_id" : "Japan",
				"name" : "Japan"
			}
		}
	],
	"writeConcernErrors" : [ ],
	"nInserted" : 1,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
}) :
BulkWriteError({
	"writeErrors" : [
		{
			"index" : 0,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: sample.countries index: _id_ dup key: { _id: \"China\" }",
			"op" : {
				"_id" : "China",
				"name" : "China"
			}
		},
		{
			"index" : 1,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: sample.countries index: _id_ dup key: { _id: \"Japan\" }",
			"op" : {
				"_id" : "Japan",
				"name" : "Japan"
			}
		}
	],
	"writeConcernErrors" : [ ],
	"nInserted" : 1,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})
BulkWriteError@src/mongo/shell/bulk_api.js:367:48
BulkWriteResult/this.toError@src/mongo/shell/bulk_api.js:332:24
Bulk/this.execute@src/mongo/shell/bulk_api.js:1186:23
DBCollection.prototype.insertMany@src/mongo/shell/crud_api.js:326:5
@(shell):1:1
>


Let’s query for the countries collection.

> db.countries.find()
{ "_id" : "India", "name" : "India" }
{ "_id" : "Japan", "name" : "Japan" }
{ "_id" : "Iran", "name" : "Iran" }
{ "_id" : "China", "name" : "China" }
{ "_id" : "Italy", "name" : "Italy" }


Italy country details are persisted even though prior documents lead to conflicts.

 

Other points to remember

a.   Ordered inserts in the default behavior in MongoDB.

b.   While executing an ordered list, each operation must wait for the previous operation to finish. so executing an ordered list will generally be slower than executing an unordered list.

c.    Ordered operations stop after an error, while unordered operations continue to process any remaining write operations in the queue.

 

 

Previous                                                    Next                                                    Home

1 comment:

  1. Irrespective of ordered/unordered can insert order in db maintained in order? So while it storing is it confirmed to process in order?

    ReplyDelete