Krenor
Krenor

Reputation: 641

MongoDB - Why does the _id index not throwing an error on duplicate entries?

I'm completely new to NoSQL databases and I'm working currently with MongoDB.

I'm trying to understand why the default _id index does not throw an error, when upserting a duplicate _id document.

As stated in the docs _id is an unique index by default

(although it doesn't show the unique flag here..)

> db.foo.getIndexes();
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.foo"
    }
]
>

So when upserting the document (started with an empty collection),
if first inserts it and then seems to "ignore" it.

> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true});
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "doe123" })

> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

So I've tried another thing and created an unique index on "name".

The result of upserting a duplicate name:

> db.foo.update({ _id: 'foo456'}, { _id: 'foo456', name: 'John Doe'}, { upsert: true});
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error collection: test.foo index: name_1 dup key: { : \"John Doe\" }"
    }
})

Why am I not getting this kind of error on a duplicate _id?


EDIT: I'm using MongoDB v.3.2.3

Upvotes: 2

Views: 1135

Answers (1)

Shrabanee
Shrabanee

Reputation: 2776

There is no reason to show duplicate index error in the first case as it is just trying to update the _id and name fields of the same record with the same value.

If you will try

  db.foo.update({ _id: '1098'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true});

you will get error, as query is trying to update record with different _id with some existing _id value.

In second case, you created a record first with name field and then you are trying update the same name in another record, which will give error as name is unique index.

Edit :-

If you are trying

 db.foo.insert({ _id: 'doe123', name: 'John Doe'});

will give you the error, as in this case you are trying to insert a record which is already present i.e. _id is unique and you are trying to create one more record with same _id value.

upsert:true :- if upsert is true and no document matches the query criteria, update() inserts a single document.

If upsert is true and there are documents that match the query criteria, update() performs an update.

Upvotes: 2

Related Questions