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

ピリオド(. )とドル記号( ) を含むフィールド名$

項目一覧

  • Overview
  • 挿入操作
  • ドキュメントを置き換える更新
  • ドキュメントを変更する更新
  • 集計パイプラインを使用した更新
  • 一般的な制限

MongoDB 5.0 では、ドル記号( $ )のプレフィックスが付いたフィールド名、またはピリオド( . )のプレフィックスが付いたフィールド名の サポートが強化 されました。 これらの文字を使用するデータソースの操作を容易にするために、データを保存するための検証ルールが更新されました。

ほとんどの場合、このようなフィールド名を使用して保存されたデータには直接アクセスできません。 これらのフィールドにアクセスするクエリでは、 $getField$setField$literalなどのヘルパー メソッドを使用する必要があります。

フィールド名の検証ルールは、すべてのタイプのストレージ操作で同じではありません。 このページでは、さまざまな挿入操作と更新操作でドル記号( $ )のプレフィックスがついたフィールド名がどのように処理されるかがまとめられています。

ドル記号($)のプレフィックスがついたフィールドは、挿入のトップレベルおよびネストされたフィールド名として使用できます。

db.sales.insertOne( {
"$price": 50.00,
"quantity": 30
} )

ドル記号($)のプレフィックスがついたフィールドは、それ以外を予約語として使用する挿入で使用できます。$inc のような演算子名や、iddbref のような単語もフィールド名として使用できます。

db.books.insertOne( {
"$id": "h1961-01",
"location": {
"$db": "novels",
"$ref": "2007042768",
"$inc": true
} } )

アップサート中に新しいドキュメントを作成する更新は、フィールド名の検証の update ではなく insert として扱われます。アップサートは、ドル記号($)のプレフィックスがついたフィールドを受け入れることができます。ただし、アップサートは、特殊なケースであるため、更新の match の部分で既存のドキュメントが選択された場合、同様の更新操作でエラーが発生する可能性があります。

このコード サンプルは upsert: true に設定されているため、クエリ用語の { "date": "2021-07-07" } に一致するドキュメントがコレクションにまだ含まれていない場合は、新しいドキュメントが挿入されます。このサンプル コードが既存のドキュメントと一致する場合、$hotel にドル記号($)のプレフィックスが付いているため更新は失敗します。

db.expenses.updateOne(
{ "date": "2021-07-07" },
{ $set: {
"phone": 25.17,
"$hotel": 320.10
} },
{ upsert: true }
)

更新演算子は、既存のフィールドを新しいドキュメントに置き換えるか、それらのフィールドを変更します。更新によって置換が実行される場合、ドル記号($)のプレフィックスがついたフィールドは最上位のフィールド名として使用できません。

次のようなドキュメントについて考えてみましょう。

{
"_id": "E123",
"address": {
"$number": 123,
"$street": "Elm Road"
},
"$rooms": {
"br": 2,
"bath": 1
}
}

既存のドキュメントを置き換える更新演算子を使用して address.$street フィールドを変更することはできますが、その方法で $rooms フィールドを更新することはできません。

db.housing.updateOne(
{ "_id": "E123" },
{ $set: { "address.$street": "Elm Ave" } }
)

集計パイプラインの一部として$setFieldを使用して、 最上位のドル記号( $ )のプレフィックス付きフィールドを$roomsのように更新します。

更新によって既存のドキュメント フィールドが、置き換えではなく変更される場合、ドル記号($)のプレフィックスがついたフィールドが最上位のフィールド名になることがあります。サブフィールドには直接アクセスできますが、最上位のフィールドにアクセスするにはヘルパー メソッドが必要です。

Tip

以下も参照してください。

このレコードのようなドキュメントがあるコレクションを考えてみましょう。

{
_id: ObjectId("610023ad7d58ecda39b8d161"),
"part": "AB305",
"$bin": 200,
"quantity": 100,
"pricing": { sale: true, "$discount": 60 }
}

pricing.$discount サブフィールドは、直接クエリできます。

db.inventory.findAndModify( {
query: { "part": { $eq: "AB305" } },
update: { $inc: { "pricing.$discount": 10 } }
} )

最上位レベルの $bin フィールドの値にアクセスするには、$getField$literal を使用します。

db.inventory.findAndModify( {
query: { $expr: {
$eq: [ { $getField: { $literal: "$bin" } }, 200 ]
} },
update: { $inc: { "quantity": 10 } }
} )

集計パイプラインのドル記号($)のプレフィックスがついたフィールドを変更するには、$replaceWith ステージで $setField$getField、および $literal 使用します。

次のような学校のレコードのコレクションを考えてみましょう。

{
"_id": 100001,
"$term": "fall",
"registered": true,
"grade": 4
}

パイプラインを使用して、ドル記号($)のプレフィックスが付いた $term フィールドを更新し、春学期の新しいコレクションを作成します。

db.school.aggregate( [
{ $match: { "registered": true } },
{ $replaceWith: {
$setField: {
field: { $literal: "$term" },
input: "$$ROOT",
value: "spring"
} } },
{ $out: "spring2022" }
] )

上記のストレージ検証ルールに加えて、ドル記号($)のプレフィックスがついたフィールド名の使用には一般的な制限があります。これらのフィールドには、次のことはできません。

  • インデックスを付ける

  • シャードキーの一部に使用する

  • を使用して検証される $jsonSchema

  • エスケープ シーケンスで変更する

  • フィールドレベル暗号化と併用する

  • _id ドキュメントのサブフィールドに使用する

警告

ドル記号($)とピリオド(.)によるデータ損失の可能性

ドル記号($)で始まるフィールド名や、ピリオド(.)を含むフィールド名を使用し、MongoDB 5.0 以前のサーバーで未確認の書き込み(書き込み確認(write concern)w=0)と組み合わせて使用すると、頻度は低いもののデータが失われる可能性があります。

insertupdate 、およびfindAndModifyコマンドを実行すると、5.0 互換のドライバーは、ドル記号( $ )のプレフィックスが付いたフィールド名またはピリオド( . )を含むフィールド名を持つドキュメントの使用に対する制限を解除します。 これらのフィールド名は、以前のドライバー バージョンではクライアント側のエラーを引き起こしていました。

ドライバーが接続されているサーバー バージョンに関係なく、制限は解除されます。5.0 ドライバーが古いサーバーにドキュメントを送信すると、エラーを送信することなくドキュメントは拒否されます。

警告

ドル記号($)とピリオド(.)に関するインポートとエクスポートの問題

MongoDB 5.0 以降、ドキュメントフィールド名に接頭辞としてドル記号($)を付けたり、ピリオド(.)を含めたりすることができます。ただし、フィールド名にこれらの記号が使用されている場合、状況によっては mongoimportmongoexport が通常どおりに動作しないことがあります。

MongoDB Extended JSON v2では、型ラッパーと、型ラッパーと同じ名前を持つフィールドを区別できません。対応する BSON 表現にドル( $)で始まるキーが含まれる可能性があるコンテキストでは、拡張 JSON 形式を使用しないでください。DBRef メカニズムは、この一般ルールの例外です。

フィールド名にピリオド(.)が含まれる状態での mongoimportmongoexport の使用にも制限があります。CSV ファイルではデータ階層を表すのにピリオド(.)が使用されるため、フィールド名のピリオド(.)はネストのレベルと誤解されます。

戻る

分散されたクエリ