[SERVER-56462] Field starting with dollar in an embedded document cannot be updated with $set Created: 29/Apr/21  Updated: 03/Jun/22  Resolved: 07/May/21

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

Type: Bug Priority: Major - P3
Reporter: Fermín Galán Assignee: Edwin Zhou
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-40070 ReplaceOne: The dollar ($) prefixed f... Backlog
Related
related to SERVER-10987 Disallow inserting documents with inv... Backlog
related to SERVER-30575 Please add escaping convention for do... Backlog
Operating System: ALL
Participants:

 Description   

I have a document in MongoDB (version 4.4.1) in a collection with a document which has a field `x` which value is an embedded document, created this way:

> db.c.insert({_id: 1, x: {$a: 2, b: 3}})
WriteResult({ "nInserted" : 1 })
> db.c.findOne({_id: 1})
{ "_id" : 1, "x" : { "$a" : 2, "b" : 3 } } 

Note there is a field in the embedded document which starts with dollar (`$a`) and a field that doesn't start with dollar (`b`). I can update the field without dolar without problem:

> db.c.updateOne({_id: 1}, {$set: {"x.b": 30}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.c.findOne({_id: 1})
{ "_id" : 1, "x" : { "$a" : 2, "b" : 30 } } 

However, if I try to update the field which starts with dollar in the same way, I get an error

> db.c.updateOne({_id: 1}, {$set: {"x.$a": 20}})
WriteError({
    "index" : 0,
    "code" : 52,
    "errmsg" : "The dollar ($) prefixed field '$a' in 'x.$a' is not valid for storage.",
    "op" : {
        "q" : {
            "_id" : 1
        },
        "u" : {
            "$set" : {
                "x.$a" : 20
            }
        },
        "multi" : false,
        "upsert" : false
    }
})

I know the recomendation in MongoDB documentation https://docs.mongodb.com/manual/reference/limits/#mongodb-limit-Restrictions-on-Field-Names which says:

The MongoDB Query Language cannot always meaningfully express queries over documents whose field names contain these characters  [$ or .]... Until support is added in the query language, the use of $ and . in field names is not recommended and is not supported by the official MongoDB drivers.

However, note this case the problem is not in the query part but in the update part, so my understanding is that that recommendation doesn't apply. Moreover, if I do a query like

db.c.find({"x.$a": 2}) 

it works.



 Comments   
Comment by Fermín Galán [ 08/May/21 ]

Dear Edwin,

Thanks for the feedback. Yes, SERVER-40070 issue seems pretty similar and probably this one is a duplicate.

Happy to know this limitation is being taken into account and is in the way to be solved. Do you have any expectation on that (i.e. in which MongoDB version the fix is planned)? Looking to SERVER-40070 it seems there is no activity since June 2020...

Thanks!

Best regards,

Fermín

Comment by Edwin Zhou [ 07/May/21 ]

Hi fermin.galanmarquez@telefonica.com,

Thank you for your detailed submission and reproduction of this behavior! I believe this issue duplicates SERVER-40070, which details an insertion of a document with a subdocument field prefixed with "$", and its limitations when modifying that field with $set and $replaceOne. This work is currently covered under a broader project that helps make $-prefixed fields more consistent.

Best,
Edwin

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