Docs Menu
Docs Home
/
MongoDBマニュアル
/ /

未定義のデータとクエリの移行

項目一覧

  • 未定義フィールドの排除
  • 既知の名前のフィールドを削除
  • 不明な名前のフィールドの排除
  • 未定義の値を null に更新
  • 既知の名前でフィールドを更新
  • 不明な名前を持つフィールドの更新
  • 未定義の値に一致するようにクエリを更新する
  • 詳細

MongoDB 8.0以降、等価一致式で nullと比較しても、 undefined値と一致しません。

たとえば、これらのドキュメントとクエリについて考えてみます。

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

MongoDB 8.0より前では、上記のクエリは次のドキュメントと一致します。

  • nameフィールドはnull_id: 1

  • nameフィールドは undefined または undefined 配列要素を含みています( _id: 2_id: 3

  • nameフィールドは存在しません( _id: 4

MongoDB 8.0 以降では、上記のクエリでは、nameフィールドが undefined であるか、 または undefined 配列要素が含まれているドキュメントは一致しません。クエリは、次の条件を満たすドキュメントのみに一致します。

  • nameフィールドは null または null 配列要素を含みています( _id: 1

  • nameフィールドは存在しません( _id: 4

このクエリ動作の変更は、次の操作にも影響します。

  • $eq

  • $in

  • $lookupは、 nullのローカルフィールドがundefinedの外部フィールドと一致しなくなったためです。

この動作の変更を考慮するには、次のことを実行します。

  • 未定義のフィールドを排除しました。

  • 未定義の値を null に更新。

  • 未定義の値に一致するようにクエリを更新する。

注意

undefined は、非推奨のBSON type です。 MongoDB Shell とドライバーの最近のバージョンでは、挿入とアップデートを実行するときに、undefined 値を null に自動的に変換します。このページのガイダンスは、古いドライバー バージョンまたはレガシーのmongo シェルからの undefined 値を持つ配置に適用されます。

ドキュメント内に undefined 値を持つフィールドを保持する必要がない場合は、それらのフィールドを削除できます。 MongoDB の柔軟なデータモデル、コレクションのドキュメントフィールドは一貫している必要はなく、ドキュメントのサブセットから特定のフィールドを削除できます。

ドキュメントから未定義のフィールドをどのように削除するかは、削除するフィールド名を知っているかどうかによって異なります。フィールド名がわかっている場合は、インデックスを使用できるため、操作のパフォーマンスが向上します。

次のいずれかを参照してください。

削除対象の undefined 値を含むフィールドの名前がわかっている場合は、次の例を使用します。この例では、peopleコレクションを更新して次の要素を削除します。

  • 値がスカラー値 undefined である場合の nameフィールド。

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

操作の実行後、peopleコレクションには次のドキュメントが含まれます。

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

undefined 値が含まれるフィールドがわからない場合は、次の例を使用して、undefined の最上位フィールドをすべて削除します。

注意

アップデートのフィールド名を指定しない場合、クエリはインデックスを使用できないため、操作はパフォーマンスが良くありません。大規模なコレクションで次の例を実行すると、クエリは遅くなり、リソースを消費する可能性があります。

次の例では、値が undefined である peopleコレクションから最上位のドキュメントフィールドを排除しています。

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

操作の実行後、peopleコレクションには次のドキュメントが含まれます。

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

注意

上記のアプローチでは、最上位のフィールドのみが変更されます。 _id: 3 を含むドキュメントには引き続き undefined 値が含まれます。これは、値が配列に表示されるためです。

undefined データ値を nullデータ型に更新できます。このアプローチを使用して、ドキュメントフィールドを保持しながら、非推奨の undefinedデータ型からデータを移行します。

未定義のフィールドをどのように更新するかは、更新対象のフィールド名がわかっているかどうかによって異なります。フィールド名がわかっている場合は、インデックスを使用できるため、操作のパフォーマンスが向上します。

次のいずれかを参照してください。

null に設定したい undefined 値を含むフィールドの名前がわかっている場合は、次の例を使用します。この例では、peopleコレクションを更新して、次の値を null に設定します。

  • 値がスカラー値 undefined である場合の nameフィールド。

  • undefined 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
}
}
}
} ]
)

操作の実行後、peopleコレクションには次のドキュメントが含まれます。

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

undefined 値が含まれるフィールドがわからない場合は、次の例を使用して、すべての undefined の最上位フィールドを null に設定します。

注意

アップデートのフィールド名を指定しない場合、クエリはインデックスを使用できないため、操作はパフォーマンスが良くありません。大規模なコレクションで次の例を実行すると、クエリは遅くなり、リソースを消費する可能性があります。

次の例では、peopleコレクションを更新して、undefined の最上位ドキュメントフィールドを 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"
}
}
}
}
}
} ]
)

操作の実行後、peopleコレクションには次のドキュメントが含まれます。

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

注意

上記のアプローチでは、最上位のフィールドのみが変更されます。 _id: 3 を含むドキュメントには引き続き undefined 値が含まれます。これは、値が配列に表示されるためです。

データ型を null から undefined に移行できない場合は、未定義の値と一致するようにクエリを書き換えることができます。このアプローチを使用しても、データには非推奨の undefined BSON型が引き続き含まれます。

null のクエリが未定義の値と一致するようにするには、undefined 型に明示的に一致するクエリ述語を追加します。例、次のクエリは、nameundefinednull 、または欠落しているドキュメントに一致します。

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

このクエリでは、 peopleコレクション内のすべてのドキュメントが返されます。

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

戻る

比較とソートの順序