Nomes de campo prefixados em dólares
Nesta página
This section summarizes how different insert and update operations
handle dollar ($
) prefixed field names.
Inserir operações
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
.
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. Upserts can accept dollar ($
) prefixed
fields. 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.
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" }
. If this sample code matches
an existing document, the update will fail since $hotel
is dollar
($
) prefixed.
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.
db.housing.updateOne( { "_id": "E123" }, { $set: { "address.$street": "Elm Ave" } } )
Usar $setField
as part of an aggregation pipeline to
update top level dollar ($
)
prefixed fields like $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.
Veja também:
Consider a collection with documents like this inventory record:
{ _id: ObjectId("610023ad7d58ecda39b8d161"), "part": "AB305", "$bin": 200, "quantity": 100, "pricing": { sale: true, "$discount": 60 } }
The pricing.$discount
subfield can be queried directly.
db.inventory.findAndModify( { query: { "part": { $eq: "AB305" } }, update: { $inc: { "pricing.$discount": 10 } } } )
Usar $getField
and $literal
to access the
value of the top level $bin
field.
db.inventory.findAndModify( { query: { $expr: { $eq: [ { $getField: { $literal: "$bin" } }, 200 ] } }, update: { $inc: { "quantity": 10 } } } )
Updates Using Aggregation Pipelines
Usar $setField
, $getField
, and
$literal
in the $replaceWith
stage to modify
dollar ($
) prefixed fields in an aggregation gasoduto.
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
gasoduto to update the dollar ($
) prefixed $term
field.
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
Be be modified with an escape sequence
Be used with Field Level Encryption
Be used as a subfield in an
_id
document
Aviso
Possible Data Loss With Dollar Signs ($) and Periods (.)
Há uma pequena chance de perda de dados ao usar nomes de campo com prefixo de cifrão ($
) ou nomes de campo que contenham pontos (.
) se esses nomes de campo forem usados em conjunto com gravações não reconhecidas de (write concern w=0
) em servidores mais antigos que o MongoDB 5.0.
Ao executar os comandos insert
, update
e findAndModify
, os drivers compatíveis com a versão 5.0 removem as restrições de uso de documentos com nomes de campo com prefixo de cifrão ($
) ou que contenham pontos (.
). Esses nomes de campo geraram um erro do lado do cliente nas versões anteriores do driver.
As restrições são removidas independentemente da versão do servidor à qual o driver está conectado. Se um driver do 5.0 enviar um documento para um servidor mais antigo, o documento será rejeitado sem enviar um erro.
Aviso
Import and Export Concerns With Dollar Signs ($) and Periods (.)
A partir do MongoDB 5.0, os nomes dos campos do documento podem ter prefixo de cifrão ($
) e podem conter pontos (.
). No entanto, mongoimport
e mongoexport
podem não funcionar como esperado em algumas situações com nomes de campo que fazem uso destes caracteres.
O JSON estendido v2 MongoDB não consegue diferenciar entre os wrappers de tipo e os campos que têm o mesmo nome dos wrappers de tipo. Não use formatos JSON estendidos em contextos onde as representações BSON correspondentes possam incluir chaves prefixadas com cifrões ($
). O mecanismo DBRef é uma exceção a esta regra geral.
Também há restrições quanto ao uso de mongoimport
e mongoexport
com pontos (.
) em nomes de campos. Como os arquivos CSV usam o ponto (.
) para representar hierarquias de dados, um ponto (.
) em um nome de campo será interpretado incorretamente como um nível de aninhamento.