A partir de MongoDB 8.0, las comparaciones con null en expresiones de coincidencia exacta no hacen coincidir valores undefined.
Por ejemplo, considera estos documentos y la query:
// create the people collection db.people.insertMany( [ { _id: 1, name: null }, { _id: 2, name: undefined }, { _id: 3, name: [ "Gabriel", undefined ] }, { _id: 4, names: [ "Alice", "Charu" ] } ] )
db.people.find( { name: null } )
Antes de MongoDB 8.0, el query anterior coincidiría con documentos donde:
El campo
nameesnull(_id: 1)El campo
nameesundefinedo contiene un elemento de arregloundefined(_id: 2y_id: 3)El campo
nameno existe (_id: 4)
A partir de MongoDB 8.0, la query anterior no coincide con documentos en que el campo name es undefined o contiene undefined elementos de arreglo. La query solo coincide con documentos en que:
El campo
nameesnullo contiene un elemento de arreglonull(_id: 1)El campo
nameno existe (_id: 4)
Este cambio de comportamiento de query también afecta estas operaciones:
Para tener en cuenta este cambio de comportamiento, puedes:
Nota
undefined es un tipo BSON obsoleto. Las versiones recientes de la MongoDB Shell y los drivers convierten automáticamente los valores de undefined a null al realizar inserciones y actualizaciones. La orientación en esta página se aplica a las implementaciones que tengan valores undefined de versiones antiguas de drivers o de la shell heredada mongo.
Remover campos no definidos
Si no necesita conservar campos con valores undefined en sus documentos, puede eliminarlos. El modelo de datos flexible de MongoDB implica que los campos de documentos de su colección no necesitan ser consistentes, por lo que puede eliminar un campo específico de un subconjunto de documentos.
La forma de remover campos indefinidos de sus documentos depende de si conoce el nombre del campo a remover. Si conoces el nombre del campo, la operación es más eficiente porque se puede usar un índice.
Consulta cualquiera de las siguientes opciones:
Remover campo con nombre conocido
Si conoces el nombre del campo que contiene valores de undefined que deseas remover, utiliza el siguiente ejemplo. El ejemplo actualiza la colección people para remover:
El campo
namesi su valor es el valor escalarundefined.undefinedelementos de la matriz en el 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" } } } } ] )
Después de ejecutar la operación, la colección people contiene estos documentos:
[ { _id: 1, name: null }, { _id: 2 }, { _id: 3, name: [ "Gabriel" ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Remover campos con nombres desconocidos
Si aún no sabes en qué campos hay valores undefined, usa el siguiente ejemplo para remover todos los campos a nivel superior undefined.
Nota
Cuando no especifiques un nombre de campo para el actualizar, la operación no será eficiente porque la query no podrá utilizar un índice. Si ejecuta el siguiente ejemplo en una colección grande, la query podría ser lenta y consumir muchos recursos.
El siguiente ejemplo remueve los campos de documentos de nivel superior de la colección people donde el valor es 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" ] } } } } } } ] )
Después de ejecutar la operación, la colección people contiene estos documentos:
[ { _id: 1, name: null }, { _id: 2 }, { _id: 3, name: [ "Gabriel", undefined ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Nota
El enfoque anterior sólo modifica los campos de nivel superior. El documento con _id: 3 todavía contiene un valor undefined porque el valor aparece en un arreglo.
Actualizar valores indefinidos a nulos
Puedes actualizar los valores de datos undefined al tipo de datos null. Usa este método para migrar tus datos desde el tipo de dato obsoleto undefined y conservar los campos de tus documentos.
La forma de actualizar los campos indefinidos depende de si conoces el nombre del campo que deseas actualizar. Si se conoce el nombre del campo, la operación es más eficiente porque puede utilizar un índice.
Consulta cualquiera de las siguientes opciones:
Actualizar campo con nombre conocido
Si conoces el nombre del campo que contiene valores de undefined que deseas establecer en null, utiliza el siguiente ejemplo. El ejemplo actualiza la colección de people para establecer los siguientes valores a null:
El campo
namesi su valor es el valor escalarundefined.undefinedelementos del arreglo que aparecen en el 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 } } } } ] )
Después de ejecutar la operación, la colección people contiene estos documentos:
[ { _id: 1, name: null }, { _id: 2, name: null }, { _id: 3, name: [ "Gabriel", null ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Actualizar Campos con Nombres Desconocidos
Si no sabe qué campos contienen valores undefined, utilice el siguiente ejemplo para establecer todos los campos de nivel superior undefined en null.
Nota
Cuando no especifiques un nombre de campo para el actualizar, la operación no será eficiente porque la query no podrá utilizar un índice. Si ejecuta el siguiente ejemplo en una colección grande, la query podría ser lenta y consumir muchos recursos.
El siguiente ejemplo actualiza la colección people para establecer los campos de documento de nivel superior undefined a 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" } } } } } } ] )
Después de ejecutar la operación, la colección people contiene estos documentos:
[ { _id: 1, name: null }, { _id: 2, name: null }, { _id: 3, name: [ "Gabriel", undefined ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
Nota
El enfoque anterior sólo modifica los campos de nivel superior. El documento con _id: 3 todavía contiene un valor undefined porque el valor aparece en un arreglo.
Actualizar consultas para que coincidan con valores indefinidos
Si no puedes migrar tus tipos de datos de null a undefined, puedes reescribir tus consultas para que coincidan con valores indefinidos. Si utiliza este método, sus datos seguirán conteniendo el tipo BSON undefined obsoleto.
Para que las queries para null coincidan con valores indefinidos, añade un predicado de query que coincida explícitamente con el tipo undefined. Por ejemplo, la siguiente query encuentra documentos donde name es undefined, null o está ausente:
db.people.find( { $or: [ { name: null }, { name: { $type: "undefined" } } ] } )
La query devuelve todos los documentos de la colección people:
[ { _id: 1, name: null }, { _id: 2, name: undefined }, { _id: 3, name: [ "Gabriel", undefined ], { _id: 4, names: [ "Alice", "Charu" ] } ]