Docs Menu
Docs Home
/ /

Migrar los datos y query no definidos

A partir de MongoDB 8.0, comparaciones con null En las expresiones de coincidencia de igualdad no coinciden con los 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 name es null (_id: 1)

  • El campo name es undefined o contiene un elemento de arreglo undefined (_id: 2 y _id: 3)

  • El campo name no 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 name es null o contiene un elemento de arreglo null (_id: 1)

  • El campo name no existe (_id: 4)

Este cambio de comportamiento de query también afecta estas operaciones:

  • $eq

  • $in

  • $lookup, porque un campo local null ya no coincide con un campo foráneo undefined.

Para tener en cuenta este cambio de comportamiento, puedes:

  • Eliminar campos no definidos.

  • Actualizar valores no definidos a nulos.

  • Actualizar consultas para que coincidan con valores no definidos.

Nota

undefined Es un tipo BSON obsoleto. Las versiones recientes de MongoDB Shell y los controladores convierten automáticamente los valores undefined a null al realizar inserciones y actualizaciones. La guía de esta página se aplica a implementaciones con valores undefined de versiones anteriores del controlador o del shell mongo heredado.

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.

Ver ya sea:

Si conoce el nombre del campo que contiene los valores undefined que desea eliminar, utilice el siguiente ejemplo. El ejemplo actualiza la colección people para eliminarla:

  • El campo name si su valor es el valor escalar undefined.

  • undefined elementos de la matriz en el campo name.

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

Si no sabe qué campos contienen valores undefined, utilice el siguiente ejemplo para eliminar todos los campos de nivel superior undefined.

Nota

Si no se especifica un nombre de campo para la actualización, la operación no es eficaz porque la consulta no puede usar un índice. Si se ejecuta el siguiente ejemplo en una colección grande, la consulta podría ser lenta y consumir muchos recursos.

El siguiente ejemplo elimina los campos de documento 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 solo modifica los campos de nivel superior. El documento con _id: 3 aún contiene un valor undefined porque este aparece en una matriz.

Puede actualizar los valores de datos undefined al tipo de dato null. Utilice este método para migrar sus datos del tipo de dato undefined obsoleto, conservando los campos de su documento.

La forma de actualizar campos indefinidos depende de si se conoce el nombre del campo a actualizar. Si se conoce el nombre del campo, la operación es más eficiente porque se puede usar un índice.

Ver ya sea:

Si conoce el nombre del campo que contiene valores undefined que desea establecer en null, utilice el siguiente ejemplo. El ejemplo actualiza la colección people para establecer los siguientes valores en null:

  • El campo name si su valor es el valor escalar undefined.

  • undefined elementos de la matriz que aparecen en el campo name.

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

Si no sabe qué campos contienen valores undefined, utilice el siguiente ejemplo para establecer todos los campos de nivel superior undefined en null.

Nota

Si no se especifica un nombre de campo para la actualización, la operación no es eficaz porque la consulta no puede usar un índice. Si se ejecuta el siguiente ejemplo en una colección grande, la consulta 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 en 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 solo modifica los campos de nivel superior. El documento con _id: 3 aún contiene un valor undefined porque este aparece en una matriz.

Si no puede migrar sus tipos de datos de null a undefined, puede reescribir sus 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 consultas de null coincidan con valores indefinidos, agregue un predicado de consulta que coincida explícitamente con el tipo undefined. Por ejemplo, la siguiente consulta coincide con documentos donde name es undefined, null o falta:

db.people.find( {
$or: [
{ name: null },
{ name: { $type: "undefined" } }
]
} )

La consulta 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" ] }
]

Volver

Comparación y orden de clasificación

En esta página