Migrar dados e queries indefinidos
Nesta página
A partir do MongoDB 8.0, as comparações com null
em expressões de correspondência de igualdade não correspondem aos valores undefined
.
Por exemplo, considere estes documentos e consulte:
// people collection [ { _id: 1, name: null }, { _id: 2, name: undefined }, { _id: 3, name: [ "Gabriel", undefined ], { _id: 4, names: [ "Alice", "Charu" ] } ]
db.people.find( { name: null } )
Antes do MongoDB 8.0, a query anterior corresponderia a documentos onde:
O campo
name
énull
(_id: 1
)O campo
name
éundefined
ou contém um elemento de arrayundefined
(_id: 2
e_id: 3
)O campo
name
não existe (_id: 4
)
A partir do MongoDB 8.0, a query anterior não corresponde a documentos em que o campo name
seja undefined
ou contenha undefined
elementos de array. A query corresponde apenas a documentos onde:
O campo
name
énull
ou contém um elemento de arraynull
(_id: 1
)O campo
name
não existe (_id: 4
)
Essa mudança de comportamento da query também afeta as operações:
Para levar em conta essa mudança de comportamento, você pode:
Observação
undefined
é um tipo de BSON obsoleto. Versões recentes do MongoDB Shell e drivers convertem automaticamente valores de undefined
para null
ao executar inserções e atualizações. A orientação nesta página se aplica a sistemas que têm valores de undefined
de versões de driver mais antigas ou shell mongo
legado .
Remover campos indefinidos
Se você não precisar manter campos com valores undefined
em seus documentos, poderá remover esses campos. O modelo de dados flexível do MongoDB significa que os campos de documento da sua coleção não precisam ser consistentes, portanto, você pode remover um campo específico de um subconjunto de documentos.
Como remover campos indefinidos de seus documentos depende se você conhece o nome do campo a ser removido. Se você souber o nome do campo , a operação terá mais desempenho porque ela pode usar um índice.
Consulte:
Remover campo com nome conhecido
Se você souber o nome do campo que contém undefined
valores que deseja remover, use o exemplo a seguir. O exemplo atualiza a coleção people
para remover:
O campo
name
se seu valor for o valor escalarundefined
.undefined
elementos de array no camponame
.
db.people.updateMany( { name: { $type: "undefined" } }, [ { $set: { "name": { $cond: { // When "name" is an array, convert { name: [ "Alice", undefined ] } // to { name: [ "Alice" ] } if: { $eq: [ { $type: "$name" }, "array" ] }, then: { $filter: { input: "$name", cond: { $not: { $eq: [ { $type: "$$this" }, "undefined" ] } } }, }, // When "name" is scalar undefined, remove it else: "$$REMOVE" } } } } ] )
Após executar a operação, a coleção people
contém estes documentos:
[ { _id: 1, name: null }, { _id: 2 }, { _id: 3, name: [ "Gabriel" ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Remover campos com nomes desconhecidos
Se você não souber quais campos contêm valores undefined
, use o exemplo a seguir para remover todos os campos de nível superior undefined
.
Observação
Quando você não especifica um nome de campo para a atualização, a operação não é executada porque a consulta não pode usar um índice. Se você executar o exemplo a seguir em uma collection grande, a query poderá ser lenta e consumir muitos recursos.
O exemplo a seguir remove os campos de documento de nível superior da coleção people
onde o valor é undefined
:
db.people.updateMany( { }, [ { $replaceWith: { // Detect undefined top-level fields under the root and remove them $arrayToObject: { $filter: { input: { $objectToArray: "$$ROOT" }, cond: { $not: { $eq: [ { $type: "$$this.v" }, "undefined" ] } } } } } } ] )
Após executar a operação, a coleção people
contém estes documentos:
[ { _id: 1, name: null }, { _id: 2 }, { _id: 3, name: [ "Gabriel", undefined ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Observação
A abordagem anterior modifica apenas campos de nível superior. O documento com _id: 3
ainda contém um valor undefined
porque o valor aparece em uma array.
Atualizar valores indefinidos para nulo
Você pode atualizar os valores de dados undefined
para o tipo de dados null
. Use essa abordagem para migrar seus dados do tipo de dados undefined
obsoleto e, ao mesmo tempo, manter os campos do documento .
Como atualizar campos indefinidos depende se você sabe o nome do campo para atualizar. Se você souber o nome do campo , a operação terá mais desempenho porque ela pode usar um índice.
Consulte:
Atualizar campo com nome conhecido
Se você souber o nome do campo que contém undefined
valores que deseja definir como null
, use o exemplo a seguir. O exemplo atualiza a coleção people
para definir os seguintes valores para null
:
O campo
name
se seu valor for o valor escalarundefined
.undefined
elementos de array que aparecem no camponame
.
db.people.updateMany( { name: { $type: "undefined" } }, [ { $set: { "name": { $cond: { // When "name" is an array, convert { name: [ "Alice", undefined ] } // to { name: [ "Alice", null ] } if: { $eq: [ { $type: "$name" }, "array" ] }, then: { $map: { input: "$name", in: { $cond: { if: { $eq: [ { $type: "$$this" }, "undefined" ] }, then: null, else: "$$this" } } }, }, // When "name" is the scalar undefined, convert to null else: null } } } } ] )
Após executar a operação, a coleção people
contém estes documentos:
[ { _id: 1, name: null }, { _id: 2, name: null }, { _id: 3, name: [ "Gabriel", null ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Atualizar campos com nomes desconhecidos
Se você não souber quais campos contêm valores undefined
, use o exemplo a seguir para definir todos os campos de nível superior undefined
como null
.
Observação
Quando você não especifica um nome de campo para a atualização, a operação não é executada porque a consulta não pode usar um índice. Se você executar o exemplo a seguir em uma collection grande, a query poderá ser lenta e consumir muitos recursos.
O exemplo a seguir atualiza a coleção people
para definir undefined
campos de documento de nível superior como null
:
db.people.updateMany( { }, [ { $replaceWith: { // Detect undefined top-level fields under the root and replace them with null $arrayToObject: { $map: { input: { $objectToArray: "$$ROOT" }, in: { $cond: { if: { $eq: [ { $type: "$$this.v" }, "undefined" ] }, then: { k: "$$this.k", v: null }, else: "$$this" } } } } } } ] )
Após executar a operação, a coleção people
contém estes documentos:
[ { _id: 1, name: null }, { _id: 2, name: null }, { _id: 3, name: [ "Gabriel", undefined ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Observação
A abordagem anterior modifica apenas campos de nível superior. O documento com _id: 3
ainda contém um valor undefined
porque o valor aparece em uma array.
Atualizar queries para corresponder a valores indefinidos
Se você não pode migrar seus tipos de dados de null
para undefined
, você pode reescrever suas queries para corresponder a valores indefinidos. Se você utilizar esta abordagem, seus dados ainda conterão o tipo de BSON undefined
obsoleto.
Para que as consultas null
correspondam a valores indefinidos, adicione um predicado de consulta que corresponda explicitamente ao tipo undefined
. Por exemplo, a query a seguir corresponde a documentos em que name
está undefined
, null
ou está ausente:
db.people.find( { $or: [ { name: null }, { name: { $type: "undefined" } } ] } )
A query retorna todos os documentos na collection people
:
[ { _id: 1, name: null }, { _id: 2, name: undefined }, { _id: 3, name: [ "Gabriel", undefined ], { _id: 4, names: [ "Alice", "Charu" ] } ]