.
) and Dollar Signs ($
).
)和美元符号($
)的字段名On this page本页内容
MongoDB 5.0 adds improved support for field names that are dollar (MongoDB 5.0增加了对以美元($
) prefixed or that contain periods (.
). $
)为前缀或包含句点(.
)的字段名的改进支持。The validation rules for storing data have been updated to make it easier to work with data sources that use these characters.存储数据的验证规则已经更新,以便更容易使用使用这些字符的数据源。
In most cases data that has been stored using field names like these is not directly accessible. 在大多数情况下,使用此类字段名存储的数据无法直接访问。You need to use helper methods like 在访问这些字段的查询中,需要使用$getField
, $setField
, and $literal
in queries that access those fields.$getField
、$setField
和$literal
等帮助器方法。
The field name validation rules are not the same for all types of storage operations. 对于所有类型的存储操作,字段名验证规则都不相同。This page summarizes how different insert and update operations handle dollar (本页总结了不同的插入和更新操作如何处理美元($
) prefixed field names.$
)前缀字段名。
Dollar (美元($
) prefixed fields are permitted as top level and nested field names for inserts.$
)前缀字段可以作为插入的顶级和嵌套字段名。
db.sales.insertOne( { "$price": 50.00, "quantity": 30 } )
Dollar (美元($
) prefixed fields are permitted on inserts using otherwise reserved words. $
)前缀字段允许在插入时使用其他保留字。Operator names like 像$inc
can be used as field names as well as words like id
, db
, and ref
.$inc
这样的运算符名可以用作字段名,id
、db
和ref
等词也一样。
db.books.insertOne( { "$id": "h1961-01", "location": { "$db": "novels", "$ref": "2007042768", "$inc": true } } )
An update which creates a new document during an upsert is treated as an 在upsert期间创建新文档的更新被视为insert
rather than an update
for field name validation. insert
,而不是字段名验证的update
。Upserts can accept dollar ($
) prefixed fields. Upserts
可以接受带美元($
)前缀的字段。However, upserts are a special case and similar update operations may cause an error if the 但是,match
portion of the update selects an existing document.upserts
是一种特殊情况,如果更新的match
部分选择了现有文档,则类似的更新操作可能会导致错误。
This code sample has 此代码示例具有upsert: true
so it will insert a new document if the collection doesn't already contain a document that matches the query term, { "date": "2021-07-07" }
. upsert:true
,因此如果集合中尚未包含与查询项{ "date": "2021-07-07" }
匹配的文档,它将插入一个新文档。If this sample code matches an existing document, the update will fail since 如果此示例代码与现有文档匹配,则更新将失败,因为$hotel
is dollar ($
) prefixed.$hotel
前缀为美元($
)。
db.expenses.updateOne( { "date": "2021-07-07" }, { $set: { "phone": 25.17, "$hotel": 320.10 } }, { upsert: true } )
Update operators either replace existing fields with new documents or else modify those fields. 更新运算符可以用新文档替换现有字段,也可以修改这些字段。In cases where the update performs a replacement, dollar (在更新执行替换的情况下,不允许将美元($
) prefixed fields are not permitted as top level field names.$
)前缀字段作为顶级字段名。
Consider a document like考虑这样一个文档:
{ "_id": "E123", "address": { "$number": 123, "$street": "Elm Road" }, "$rooms": { "br": 2, "bath": 1 } }
You could use an update operator that replaces an existing document to modify the 您可以使用替换现有文档的更新运算符来修改address.$street
field but you could not update the $rooms
field that way.address.$street
字段,但您无法以这种方式更新$rooms
字段。
db.housing.updateOne( { "_id": "E123" }, { $set: { "address.$street": "Elm Ave" } } )
Use 使用$setField
as part of an aggregation pipeline to update top level dollar ($
) prefixed fields like $rooms
.$setField
作为聚合管道的一部分来更新顶级美元($
)前缀字段,如$rooms
。
When an update modifies, rather than replaces, existing document fields, dollar (当更新修改而不是替换现有文档字段时,以美元($
) prefixed fields can be top level field names. $
)为前缀的字段可以是顶级字段名。Subfields can be accessed directly, but you need a helper method to access the top level fields.子字段可以直接访问,但您需要一个助手方法来访问顶级字段。
Consider a collection with documents like this inventory record:考虑一个包含以下inventory
记录的集合:
{ _id: ObjectId("610023ad7d58ecda39b8d161"), "part": "AB305", "$bin": 200, "quantity": 100, "pricing": { sale: true, "$discount": 60 } }
The pricing.$discount
subfield can be queried directly.pricing.$discount
子字段可以直接查询。
db.inventory.findAndModify( { query: { "part": { $eq: "AB305" } }, update: { $inc: { "pricing.$discount": 10 } } } )
Use 使用$getField
and $literal
to access the value of the top level $bin
field.$getField
和$literal
访问顶级$bin
字段的值。
db.inventory.findAndModify( { query: { $expr: { $eq: [ { $getField: { $literal: "$bin" } }, 200 ] } }, update: { $inc: { "quantity": 10 } } } )
Use 在$setField
, $getField
, and $literal
in the $replaceWith
stage to modify dollar ($
) prefixed fields in an aggregation pipeline.$replaceWith
阶段中使用$setField
、$getField
和$literal
修改聚合管道中带美元($
)前缀的字段。
Consider a collection of school records like:考虑一个school
记录集合,比如:
{ "_id": 100001, "$term": "fall", "registered": true, "grade": 4 }
Create a new collection for the spring semester using a pipeline to update the dollar (使用管道更新以美元($
) prefixed $term
field.$
)为前缀的$term
字段,为春季学期创建一个新集合。
db.school.aggregate( [ { $match: { "registered": true } }, { $replaceWith: { $setField: { field: { $literal: "$term" }, input: "$$ROOT", value: "spring" } } }, { $out: "spring2022" } ] )
In addition to the storage validation rules above, there are some general restrictions on using dollar (除了上面的存储验证规则外,使用美元($
) prefixed field names. $
)前缀字段名还有一些一般限制。These fields cannot:这些字段不能:
$jsonSchema
$jsonSchema
进行验证_id
document_id
文档中用作子字段$
)和句点(.
)可能导致数据丢失There is a small chance of data loss when using dollar (如果在早于MongoDB 5.0的服务器上,使用带美元($
) prefixed field names or field names that contain periods (.
) if these field names are used in conjunction with unacknowledged writes (write concern w=0
) on servers that are older than MongoDB 5.0.$
)前缀的字段名或包含句点(.
)的字段名与未确认写入(写入关注点w=0
)结合使用,则数据丢失的可能性很小。
When running insert, update, and findAndModify commands, drivers that are 5.0 compatible remove restrictions on using documents with field names that are dollar (当运行insert、update和findAndModify命令时,与5.0兼容的驱动程序将取消对使用字段名前缀为美元($
) prefixed or that contain periods (.
). $
)或包含句点(.
)的文档的限制。These field names generated a client-side error in earlier driver versions.这些字段名在早期驱动程序版本中生成了客户端错误。
The restrictions are removed regardless of the server version the driver is connected to. 无论驱动程序连接到哪个服务器版本,这些限制都会被删除。If a 5.0 driver sends a document to an older server, the document will be rejected without sending an error.如果5.0驱动程序将文档发送到较旧的服务器,文档将被拒绝,且不会发送错误。
$
)和句号(.
)的导入导出问题Starting in MongoDB 5.0, document field names can be dollar (从MongoDB 5.0开始,文档字段名可以以美元($
) prefixed and can contain periods (.
). $
)为前缀,并且可以包含句点(.
)。However, 然而,在某些使用这些字符的字段名的情况下,mongoimport
and mongoexport
may not work as expected in some situations with field names that make use of these characters.mongoimport
和mongoexport
可能无法正常工作。
MongoDB Extended JSON v2 cannot differentiate between type wrappers and fields that happen to have the same name as type wrappers. 无法区分类型包装和恰好与类型包装同名的字段。Do not use Extended JSON formats in contexts where the corresponding BSON representations might include dollar (在相应的BSON表示可能包含美元($
) prefixed keys. $
)前缀键的上下文中,不要使用扩展JSON格式。The DBRef mechanism is an exception to this general rule.DBRef机制是此一般规则的例外。
There are also restrictions on using 在使用mongoimport
and mongoexport
with periods (.
) in field names. mongoimport
和mongoexport
时,还存在句点(.
)的限制在字段名中。Since CSV files use the period (因为CSV文件使用句点(.
) to represent data hierarchies, a period (.
) in a field name will be misinterpreted as a level of nesting..
)要表示数据层次结构,请使用句点(.
)在字段中,名称将被误解为嵌套级别。