CODEMONDAY
Published in

CODEMONDAY

MongoDB: database key and E11000 debugging

E11000 is somewhat generalized error that can have multiple causes.

My case belongs to basic error but can be hard to discover. We spent 4–5 hours finding this. So we hope this might benefit some developer who search the MongoDB error message on the internet.

Real life example

This is from our real ticketing system app.

We have a ticket database and we would like to insert the sample record.

> db.tickets.insert({
ticketType:'one-day pass',
ticketNumber: 1,
issueDate: '2020-04-03'
...
})
=> ok!> db.tickets.insert({
ticketType:'round trip',
ticketNumber: 2,
issueDate: '2020-04-03'
...
})
=> Error!

And it is showing some confusing error message

WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: ticket.tickets index: ticket_number_1 dup key: { ticket_number: null }"
}
})

We don’t have ticket_number on our system how can we have an error on that duplication key.

We create the new database and try to insert. It’s working but we would like to trace to the cause of this, so we investigate it.

Auto-set to null on database index

Here is the bug. Someone added ticket_number typos instead of ticketNumber as a database index key in our app.

The database index is something required to represent each record in the database. If not specified, it generates null.

Here is the problem. The first record goes in and the typos field ticket_number is set to null.

The ticket_number is set to unique so when the second record goes in it is also set ticket_number to null, so that it throw the key duplication error.

We finally find the typos by getting the database index:

> db.tickets.getIndexes()[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "ticket.tickets"
},
{
"v" : 2,
"unique" : true,
"key" : {
"ticket_number" : 1
},
"name" : "ticket_number_1",
"ns" : "ticket.tickets",
"background" : true
}
]

This first object is the default key ObjectId and the second one is the typos ticket_number we want to correct it to ticketNumber. We have to backup or remove all record before reset the key.

> db.tickets.dropIndex({ticketNumber: 1})
> db.tickets.createIndex(
{ticketNumber: 1},
{unique: true, background: true, name: 'ticketNumberIndex'}
)
Check the result> db.tickets.getIndexes()...
{
"v" : 2,
"unique" : true,
"key" : {
"tickerNumber" : 1
},
"name" : "ticketNumberIndex",
"ns" : "ticket.tickets",
"background" : true
}
]

Note: the background flag is set due to make database indexing process on the background for faster query and insert.

Here we go we are now done fixing this problem.

Cheers.

Web Application | Software | IoT

www.codemonday.com

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store