在这篇文章MongoDB finding nested elements上,作者声称mongodb文档结构是
car : { "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}}
当我试图重现这个问题时,我遇到了mongodb插入的一些奇怪的行为
在上面的示例数据上运行插入时,我收到了以下错误
> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}}})
Tue Jan 24 14:09:07 uncaught exception: field names cannot start with $ [$oid]
它表示字段名称不能以$
开头。
如果是这种情况,如果我从oid中移除$
并留下剩余的$ref
& $id
未触及
> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "oid" : "4e8478ace4b0dea06288ad63"}}})
> db.sample.find()
{ "_id" : ObjectId("4f1e6fbc403aae757ec6dea5"), "car" : { "$ref" : "cars", "$id" : { "oid" : "4e8478ace4b0dea06288ad63" } } }
令人惊讶的是它起作用了。现在它接受以$
开头的字段此外,当我尝试此查询时
> db.sample.insert({ "$ref" : "cars" })
document to insert can't have $ fields
我收到了错误。
我不明白是什么原因造成的?任何人都有一个清晰的想法?
答案 0 :(得分:4)
$id
和$ref
是dbrefs使用的特殊标识符。否则,不允许以$
开头的字段名称。
但是,您的第一级文档本身不能是dbref,因此错误“要插入的文档不能包含$ fields”。
但是,允许dbrefs作为子文档,例如(来自official docs)
"name" : "Joe",
"classes" : [
{
"$ref" : "courses",
"$id" : ObjectId("4b0552b0f0da7d1eb6f126a1")
}
]
现在$oid
不是特殊标识符,因为$
具有特殊语义而不被允许:想想$inc
。这是一个运算符,但如果允许$
字段名称,它也可以是字段的名称。
使用positional operator in updates:
时必须小心位置运算符不能与upsert组合,因为它需要匹配的数组元素。如果您的更新导致插入,则“$”将字面上用作字段名称。
答案 1 :(得分:1)