Field Names with Periods (.
) and Dollar Signs ($
)带句点(.
)和美元符号($
)的字段名
.
) and Dollar Signs ($
)On this page本页内容
Overview概述
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.$
)为前缀的字段名。
Insert operations插入操作
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 在insert
rather than an update
for field name validation. upsert
期间创建新文档的update
被视为insert
,而不是字段名称验证的更新。Upserts can accept dollar ($
) prefixed fields. upsert
可以接受以美元($
)为前缀的字段。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.upsert
是一种特殊情况,如果更新的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 }
)
Document Replacing Updates文档替换更新
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
。
Document Modifying Updates文档修改更新
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.子字段可以直接访问,但您需要一个辅助方法来访问顶级字段。
See also: 另请参阅:
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 } }
} )
Updates Using Aggregation Pipelines使用聚合管道的更新
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:考虑一组学校记录,如:
{
"_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" }
] )
General Restrictions一般限制
In addition to the storage validation rules above, there are some general restrictions on using dollar (除了上面的存储验证规则之外,对于使用以美元($
) prefixed field names. $
)为前缀的字段名,还有一些常规限制。These fields cannot:这些字段不能:
Be indexed编制索引Be used as part of a shard key用作分片键的一部分Be validated using使用$jsonSchema
$jsonSchema
进行验证Be be modified with an escape sequence使用转义序列进行修改Be used with Field Level Encryption与字段级加密一起使用Be used as a subfield in an用作_id
document_id
文档中的子字段
Possible Data Loss With Dollar Signs ($) and Periods (.)美元符号($
)和句点(.
)可能的数据丢失
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 ($
) prefixed or that contain periods (.
). These field names generated a client-side error in earlier driver versions.insert
、update
和findAndModify
命令时,与5.0兼容的驱动程序将删除对使用字段名称以美元($
)为前缀或包含句点(.
)的文档的限制。这些字段名称在早期的驱动程序版本中生成了客户端错误。
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驱动程序将文档发送到较旧的服务器,则该文档将被拒绝而不会发送错误。
Import and Export Concerns With Dollar Signs ($) and Periods (.)美元符号($
)和点号(.
)的导入导出问题
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. MongoDB Extended JSON v2无法区分类型包装器和碰巧与类型包装器同名的字段。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..
)表示数据层次结构,因此字段名称中的句点(..)将被误解为嵌套级别。