Hi, I’ve just found out that it is not possible to replace document using ReplaceOne (or FindOneAndReplace) while existing document and the new document have different _id, BUT while also filtering by other properties than _id. I would like to know why?
Here is an example:
await collection.ReplaceOneAsync(
doc => doc.Property1 == entity.Property1 && doc.Property2 == entity.Property2,
entity,
new ReplaceOptions() { IsUpsert = true },
ct);
‘entity’ object has the Id field set (GUID) and different than doc _id that is found by filter conditions (Property1 and Property2).
The error I am getting:
‘A bulk write operation resulted in one or more errors. WriteErrors: [ { Category : “Uncategorized”, Code : 66, Message : “After applying the update, the (immutable) field ‘_id’ was found to have been altered to _id: UUID(”{guid-id}“)” } ].’
Thanks to anybody who knows why there is this constrain (or feature). 
Hi @Ondrej_Svacina ,
Welcome to the MongoDB Community Forums! Are you specifying the _id
field of the new entity or is it auto generated? You can find more details about replacing a document using the .NET/C# driver here. Please note that the _id
field itself is immutable for a document once inserted. On the other hand, IsUpsert
is used when you want to insert the document if no documents match the query filter specified. Hope that helps.
Thanks,
Rishit.
Hi @Rishit_Bhatia ,
thanks for the response.
Yes, I’m specifying _id field as GUID in my application, so both existing document in DB and new replacing entity have GUID _id.
I understand that I cannot update _id field when UPDATING document, but I am trying to REPLACE whole document, moreover in ReplaceOne function I am filtering by other fields, not by _id. So I am curious why this is not possible.
Hi @Ondrej_Svacina ,
What you’re mentioning is possible. Looking at the error while trying to replicate this, this is happening because the default value of the _id
is being serialized. There are two ways of doing this type of upsert:
- Configure the POCO to NOT serialize the default
_id
value
[BsonIgnoreIfDefault]
[BsonGuidRepresentation(GuidRepresentation.Standard)]
public Guid Id { get; set; }
- Assign the
_id
value for the new entity to be same as the one you are trying to replace.
As you can see in the replacement parameter here, The <replacement> document cannot specify an _id value that differs from the replaced document.
We’ll update our documentation to clarify this further. Let me know if that works for you.
Thanks,
Rishit.