Q: Why can’t I update or edit the _id field in Studio 3T?
A: Because you can’t update the _id
field in MongoDB.
Oh, yes, I’d better explain in a little more detail. First, let us talk about what the _id
field is.
All about the _id field
The _id
field is a very special field in MongoDB. It exists in every document in every collection and within any collection is unique.
Make a document and if it doesn’t have an _id
field, MongoDB will make one for you – using an ObjectID. ObjectID was pretty much designed to be the value in an _id
field. If you do create a document with an _id
field, you’ll have to ensure that the value of the field is unique because the _id
has to be unique.
The _id
field gets a unique index automatically too. That’s what adds the requirement for _id
fields to be unique. And that means you can’t have the same _id
for any two documents in a collection.
As the _id
field is immutable, you cannot change it and that’s by design. This field is all about being the immovable reference to the document. Changing the _id, if allowed, could start off index rebuilding. That in turn could end up requiring the entire collection to be locked at some level while that happened. So, MongoDB avoids all that and declares the _id
immutable. With it not changing, MongoDB can make assumptions about how to handle the index for _id
more effectively as it is typically the most accessed field in the database.
The biggest indication that you should not regard the _id
field as part of your schema is the underscore at the start. Many developers and some languages use that as an indication that a variable is for internal/private use only and that’s a good way to look at _id
.
How do I change the _id field then?
Well, ideally you don’t. MongoDB won’t let you:
db> db.listings.updateOne({}, { $set: { _id:ObjectId() }}) MongoServerError: Performing an update on the path '_id' would modify the immutable field '_id'
You may consider the option to delete the document and reinsert it with a new _id
field, but you run a number of risks doing that. Your new _id
may not be unique and the insert will fail. Or something bad happens to the connection and the insert fails.
Whichever way, the original document will be no longer be there. Ah, you may think, what if I insert the new document then delete the old document. Well, the issue of the new _id
not being unique still exists. Add to that, if there’s another unique index for the collection, the new record will be rejected for failing the uniqueness constraint of that index.
Consider it a design problem. If you want to have a field which can be changed on demand and is indexed, then create a field and an index where you can do that. You can decide on whether you want that index to be unique or not, something you don’t get to select if you are loading the _id
field with important meaningful values.
At the end of the day, there’s a lot of good reasons for leaving the _id
field in its immutable isolation.