带句点的字段名称
本节总结了如何插入、查询并更新字段名称包含句点的文档。
插入带句点的字段名称
要插入包含带句点的字段名称的文档,请将字段名称放入引号。
以下命令将插入一个包含字段名称 price.usd
的文档:
db.inventory.insertOne( { "item" : "sweatshirt", "price.usd": 45.99, "quantity": 20 } )
查询包含句点的字段
要查询包含句点的字段,请使用 $getField
操作符。
以下查询返回 price.usd
字段大于 40
的文档:
db.inventory.find( { $expr: { $gt: [ { $getField: "price.usd" }, 40 ] } } )
[ { _id: ObjectId("66145f9bcb1d4abffd2f1b50"), item: 'sweatshirt', 'price.usd': 45.99, quantity: 20 } ]
如果您不使用 $getField
,MongoDB 会将带有句点的字段名称视为嵌入式对象。例如,以下查询匹配price
字段内的usd
字段大于 40
的文档:
db.inventory.find( { "price.usd": { $gt: 40 } } )
前面的查询将与此文档匹配:
{ "item" : "sweatshirt", "price": { "usd": 45.99 }, "quantity": 20 }
更新包含句点的字段
要更新包含句点的字段,请使用带有 $setField
操作符的聚合管道。
以下操作将 price.usd
字段设置为 29.99
:
db.inventory.updateOne( { "item": "sweatshirt" }, [ { $replaceWith: { $setField: { field: "price.usd", input: "$$ROOT", value: 29.99 } } } ] )
如果您不使用 $setField
,MongoDB 会将带有句点的字段名称视为嵌入式对象。例如,以下操作不会更新现有的 price.usd
字段,而是插入一个新字段 usd
,嵌入在 price
字段中:
db.inventory.updateOne( { "item": "sweatshirt" }, { $set: { "price.usd": 29.99 } } )
正在生成文档:
[ { _id: ObjectId("66145f9bcb1d4abffd2f1b50"), item: 'sweatshirt', 'price.usd': 45.99 quantity: 20, price: { usd: 29.99 } } ]
有关使用聚合管道进行更新的更多示例,请参阅使用聚合管道进行更新。
避免不明确的字段名称
请勿使用与嵌入字段的点表示法相同的字段名称。如果某个文档有嵌入字段 { "a" : { "b": ... } }
,则该集合中的其他文档不应具有顶级字段 "a.b"
。
如果您可以以相同的方式引用嵌入式字段和顶级字段,索引和分片操作将发生在嵌入式字段上。当集合具有以相同方式引用的嵌入式字段时,您无法对顶级字段"a.b"
索引或分片。
示例,如果您的集合包含同时具有嵌入式字段{ "a" : { "b": ... } }
和顶级字段"a.b"
的文档,索引和分片操作将在嵌入式字段上进行。当您的集合还包含嵌入式字段{ "a" : { "b": ... } }
时,无法对顶级字段"a.b"
进行索引或分片。