mongodb字段的奇怪行为以$开头

Ram*_*Vel 5 exception special-characters mongodb

MongoDB发现嵌套元素的帖子中,作者声称mongodb文档结构是

      car : { "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}}
Run Code Online (Sandbox Code Playgroud)

当我试图重现这个问题时,我遇到了mongodb插入的一些奇怪的行为

在上面的示例数据上运行插入时,我得到了以下错误

> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}}})
Tue Jan 24 14:09:07 uncaught exception: field names cannot start with $ [$oid]
Run Code Online (Sandbox Code Playgroud)

它说字段名称不能以$.

如果是这样的话,如果我$从oid中移除并留下剩下的$ref&$id未触及的话,它应该不起作用

    > db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "oid" : "4e8478ace4b0dea06288ad63"}}})
    > db.sample.find()
{ "_id" : ObjectId("4f1e6fbc403aae757ec6dea5"), "car" : { "$ref" : "cars", "$id" : { "oid" : "4e8478ace4b0dea06288ad63" } } }
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是它有效.现在它接受以$开头的字段

当我尝试这个查询时

> db.sample.insert({ "$ref" : "cars" })
document to insert can't have $ fields
Run Code Online (Sandbox Code Playgroud)

我收到了错误.

我不明白是什么原因造成的?谁有明确的想法?

mne*_*syn 5

$id$ref是用于dbrefs 的特殊标识符。否则,$不允许以 a 开头的字段名称。

但是,您的第一级文档本身不能是 dbref,因此会出现“要插入的文档不能有 $ 字段”的错误。

但是,dbrefs 允许作为子文档,例如(来自官方文档

"name" : "Joe",
"classes" : [
        {
                "$ref" : "courses",
                "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1")
        }
]
Run Code Online (Sandbox Code Playgroud)

Now$oid不是一个特殊的标识符,也是不允许的,因为它$有特殊的语义:想想$inc. 那是一个运算符,但如果$允许字段名称,它也可以是字段的名称。

在更新中使用位置运算符时必须小心:

位置运算符不能与 upsert 结合使用,因为它需要匹配的数组元素。如果您的更新导致插入,则“$”字面上将用作字段名称。