Database Manual / Introduction / BSON Types

Migrate Undefined Data and Queries迁移未定义的数据和查询

Starting in MongoDB 8.0, comparisons to null in equality match expressions don't match undefined values.从MongoDB 8.0开始,相等匹配表达式中与null的比较不匹配undefined的值。

For example, consider these documents and 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 } )

Prior to MongoDB 8.0, the preceding query would match documents where:在MongoDB 8.0之前,前面的查询将匹配以下文档:

Starting in MongoDB 8.0, the preceding query does not match documents where the name field is undefined or contains undefined array elements. The query only matches documents where:从MongoDB 8.0开始,前面的查询与name字段是undefined或包含undefined数组元素的文档不匹配。查询仅匹配以下文档:

This query behavior change also impacts these operations:此查询行为更改也会影响以下操作:

To account for this behavior change, you can:为了解释这种行为变化,您可以:

Note

undefined is a deprecated BSON type. Recent versions of the MongoDB Shell and drivers automatically convert undefined values to null when performing inserts and updates. undefined是一种已弃用的BSON类型。最新版本的MongoDB Shell和驱动程序在执行插入和更新时会自动将undefined值转换为nullThe guidance on this page applies to deployments that have undefined values from older driver versions or legacy mongo shell.此页面上的指导适用于具有来自旧驱动程序版本或遗留mongo shell的undefined值的部署。

Remove Undefined Fields删除未定义的字段

If you don't need to keep fields with undefined values in your documents, you can remove those fields. MongoDB's flexible data model means your collection's document fields do not need to be consistent, so you can remove a particular field from a subset of documents.如果您不需要在文档中保留具有undefined值的字段,则可以删除这些字段。MongoDB的灵活数据模型意味着您的集合的文档字段不需要保持一致,因此您可以从文档子集中删除特定字段。

How to remove undefined fields from your documents depends on whether you know the field name to remove. If you know the field name, the operation is more performant because it can use an index.如何从文档中删除未定义的字段取决于您是否知道要删除的字段名称。如果您知道字段名,则操作性能更高,因为它可以使用索引。

See either:请参阅:

Remove Field with Known Name删除具有已知名称的字段

If you know the name of the field that contains undefined values that you want to remove, use the following example. The example updates the people collection to remove:如果您知道包含要删除的undefined值的字段的名称,请使用以下示例。该示例更新了要删除的people集合:

  • The name field if its value is the scalar value undefined.name字段(如果其值是标量值undefined)。
  • undefined array elements in the name field.name字段中undefined的数组元素。
db.people.updateMany(
{ name: { $type: "undefined" } },
[ {
$set: {
"name": {
$cond: {
// When "name" is an array, convert { name: [ "Alice", undefined ] }当“name”是数组时,将{ name: [ "Alice", undefined ] }
// to { name: [ "Alice" ] }转换为{ name: [ "Alice" ] }
if: {
$eq: [ { $type: "$name" }, "array" ]
},
then: {
$filter: {
input: "$name",
cond: {
$not: { $eq: [ { $type: "$$this" }, "undefined" ] }
}
},
},
// When "name" is scalar undefined, remove it当“name”是标量undefined时,就删除它
else: "$$REMOVE"
}
}
}
} ]
)

After you run the operation, the people collection contains these documents:运行操作后,people集合包含以下文档:

[
{ _id: 1, name: null },
{ _id: 2 },
{ _id: 3, name: [ "Gabriel" ] }
{ _id: 4, names: [ "Alice", "Charu" ] }
]

Remove Fields with Unknown Names删除名称未知的字段

If you don't know which fields contain undefined values, use the following example to remove all undefined top-level fields.如果您不知道哪些字段包含undefined的值,请使用以下示例删除所有undefined的顶级字段。

Note

When you don't specify a field name for the update, the operation is not performant because the query can't use an index. If you run the following example on a large collection, the query might be slow and resource-intensive.如果不为更新指定字段名,则操作将无法执行,因为查询无法使用索引。如果在大型集合上运行以下示例,查询可能会很慢且资源密集。

The following example removes top-level document fields from the people collection where the value is undefined:以下示例从people集合中删除值是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" ] }
}
}
}
}
} ]
)

After you run the operation, the people collection contains these documents:运行操作后,people集合包含以下文档:

[
{ _id: 1, name: null },
{ _id: 2 },
{ _id: 3, name: [ "Gabriel", undefined ] }
{ _id: 4, names: [ "Alice", "Charu" ] }
]

Note

The preceding approach only modifies top-level fields. The document with _id: 3 still contains an undefined value because the value appears in an array.上述方法仅修改顶级字段。_id: 3的文档仍然包含一个未定义的值,因为该值出现在数组中。

Update Undefined Values to Null将未定义值更新为Null

You can update undefined data values to the null data type. Use this approach to migrate your data off of the deprecated undefined data type while retaining your document fields.您可以将undefined的数据值更新为null数据类型。使用此方法将数据从弃用的undefined数据类型中迁移出来,同时保留文档字段。

How to update undefined fields depends on whether you know the field name to update. If you know the field name, the operation is more performant because it can use an index.如何更新未定义的字段取决于您是否知道要更新的字段名称。如果您知道字段名,则操作性能更高,因为它可以使用索引。

See either:请参阅:

Update Field with Known Name用已知名称更新字段

If you know the name of the field that contains undefined values that you want to set to null, use the following example. The example updates the people collection to set the following values to null:如果您知道包含要设置为nullundefined值的字段的名称,请使用以下示例。该示例更新people集合,将以下值设置为null

  • The name field if its value is the scalar value undefined.name字段(如果其值是标量值undefined)。
  • undefined array elements that appear in the name field.name字段中出现的undefined数组元素。
db.people.updateMany(
{ name: { $type: "undefined" } },
[ {
$set: {
"name": {
$cond: {
// When "name" is an array, convert { name: [ "Alice", undefined ] }将“name”是数组时,将{ name: [ "Alice", undefined ] }
// to { name: [ "Alice", null ] }转换为{ 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当“name”是标量undefined时,就转换为null
else: null
}
}
}
} ]
)

After you run the operation, the people collection contains these documents:运行操作后,people集合包含以下文档:

[
{ _id: 1, name: null },
{ _id: 2, name: null },
{ _id: 3, name: [ "Gabriel", null ] }
{ _id: 4, names: [ "Alice", "Charu" ] }
]

Update Fields with Unknown Names更新具有未知名称的字段

If you don't know which fields contain undefined values, use the following example to set all undefined top-level fields to null.如果您不知道哪些字段包含undefined的值,请使用以下示例将所有undefined的顶级字段设置为null

Note

When you don't specify a field name for the update, the operation is not performant because the query can't use an index. If you run the following example on a large collection, the query might be slow and resource-intensive.如果不为更新指定字段名,则操作将无法执行,因为查询无法使用索引。如果在大型集合上运行以下示例,查询可能会很慢且资源密集。

The following example updates the people collection to set undefined top-level document fields to null:以下示例更新people集合,将undefined的顶级文档字段设置为null

db.people.updateMany(
{ },
[ {
$replaceWith: {
// Detect undefined top-level fields under the root and replace them with null检测根目录下未定义的顶级字段,并将其替换为null
$arrayToObject: {
$map: {
input: { $objectToArray: "$$ROOT" },
in: {
$cond: {
if: { $eq: [ { $type: "$$this.v" }, "undefined" ] },
then: { k: "$$this.k", v: null },
else: "$$this"
}
}
}
}
}
} ]
)

After you run the operation, the people collection contains these documents:运行操作后,people集合包含以下文档:

[
{ _id: 1, name: null },
{ _id: 2, name: null },
{ _id: 3, name: [ "Gabriel", undefined ] }
{ _id: 4, names: [ "Alice", "Charu" ] }
]

Note

The preceding approach only modifies top-level fields. The document with _id: 3 still contains an undefined value because the value appears in an array.上述方法仅修改顶级字段。_id: 3的文档仍然包含一个undefined的值,因为该值出现在数组中。

Update Queries to Match Undefined Values更新查询以匹配未定义的值

If you can't migrate your data types from null to undefined, you can rewrite your queries to match undefined values. If you use this approach, your data will still contain the deprecated undefined BSON type.如果你不能将数据类型从null迁移到undefined,你可以重写查询以匹配undefined值。如果使用这种方法,您的数据仍将包含已弃用的undefinedBSON类型。

To have queries for null match undefined values, add a query predicate that explicitly matches the undefined type. For example, the following query matches documents where name is undefined, null, or missing:要使对null的查询匹配未定义的值,请添加一个明确匹配undefined类型的查询谓词。例如,以下查询匹配nameundefinednull或缺失的文档:

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

The query returns all documents in the people collection:查询返回people集合中的所有文档:

[
{ _id: 1, name: null },
{ _id: 2, name: undefined },
{ _id: 3, name: [ "Gabriel", undefined ],
{ _id: 4, names: [ "Alice", "Charu" ] }
]

Learn More了解更多