[SERVER-56855] $set tries to update _id with case insensitive collation Created: 11/May/21  Updated: 27/Oct/23  Resolved: 12/May/21

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: 4.4.5
Fix Version/s: None

Type: Improvement Priority: Minor - P4
Reporter: Nitin Katkam Assignee: Eric Sedor
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
Participants:

 Description   

Problem Description

This initially started off as TOOLS-2865

When performing an update with a $set containing an _id, the server does not ignore the new _id value if it is the same as the current value when using a case-insensitive collation.

Steps to Reproduce

db.createCollection("testimpcase", {collation: {locale: "en", strength: 1}})
db.testimpcase.insertOne({_id: "abc", value: 1})
db.testimpcase.updateOne({_id: "abc"}, {"$set" : { _id: "ABC"}})

Expected Results

The server should return a 0 documents modified.

Actual Results

Error, _id is immutable

Additional Notes

 



 Comments   
Comment by Nitin Katkam [ 12/May/21 ]

Let's close this server ticket. On TOOLS-2865, it's been acknowledged that this is not a server issue and has to be fixed in MongoImport.

Comment by Nitin Katkam [ 12/May/21 ]

I agree with you on the change in case being a real change (Eg. if someone accidentally typed a country code in lower case and the DB didn't allow changing to upper case, they wouldn't be able to run an update query to correct it).

UPDATE: TOOLS-2865 has been re-opened (was "Works as designed", is "In Progress")

The expectation from the Tools team was that if query 2 (below) works then query 3 should work the same way because, if the filter for _id matches the document, it shouldn't be setting a value against _id (On a separate note, if I were writing a custom import tool, I wouldn't be including the _id within the $set, but this is how MongoImport works)

 

> db.createCollection("bugrepro", {collation:{locale:"en",strength:1)}}

{{

{ "ok" : 1 }

}}

//QUERY 1: This is to create the initial document

> db.bugrepro.updateOne({_id: "nitin"}, {$set: {_id: "nitin", counter: 1, {upsert: true})}}

{{

{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : "nitin"}

}}

//QUERY 2: The filter matches lowercase _id and the $set has no change with lowercase _id

> db.bugrepro.updateOne({_id: "nitin"}, {$set: {_id: "nitin", counter: 2, {upsert: true})}}

{{

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

}}

//QUERY 3: The filter matches initcaps _id and the $set tries to change lowercase _id to initcaps

> db.bugrepro.updateOne({_id: "Nitin"}, {$set: {_id: "Nitin", counter: 3, {upsert: true})}}

WriteError({ "index" : 0, "code" : 66, "errmsg" : "Performing an update on the path '_id' would modify the immutable field '_id'",...})

Comment by Eric Sedor [ 11/May/21 ]

Collection-level collation informs default index and query collation arguments, which govern how indexes are created and how the queries that use them perform comparisons.

But, collation doesn't impact the values stored in documents themselves. Changing the case of a value in a document (_id or not) is a real change, independent of how a document's index keys are collated, so I'm not sure it makes sense for collation on an index on a field to change how errors are returned when updating. What do you think nitin.katkam?

Generated at Thu Feb 08 05:40:22 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.