Menu Docs

Nomes de campo prefixados em dólares

This section 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.

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 }
)

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.

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 } }
} )

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" }
] )

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.