MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBでネストされた配列(サブ配列の中のサブ配列)から要素を削除する方法

MongoDBでは、配列の中にさらに配列がネストしている構造(サブ配列の中のサブ配列)から特定の要素を削除したいケースがあります。このような場合、$pull 演算子と位置指定演算子「$」を組み合わせることで実現できます。

本記事では、実際のコード例を通じて、二重にネストされた配列から要素を取り除く手順をわかりやすく解説します。

1. サンプルコレクションの作成

まず、テスト用のドキュメントを含むコレクションを作成しましょう。

> db.demo679.insertOne(
...     {
...        id:1,
...        "details": [
...           {
...              CountryName:"US",
...              "information": [
...
...                 { "Name": "Chris", "FirstName": "Name=Chris" },
...
...                 {"Name": "Bob", "FirstName": "Name=Bob" }
...              ]
...           },
...           {
...              CountryName:"UK",
...              "information": [
...
...                 { "Name": "Robert", "FirstName": "Name=Robert" },
...
...                 {"Name": "Sam", "FirstName": "Name=Sam" }
...              ]
...           }
...        ]
...    }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ea442cf04263e90dac943fd")
}

このコレクションには、「US」と「UK」という2つの国情報があり、それぞれの information 配列の中に人物データが格納されています。

2. 作成したドキュメントの確認

find() メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。

> db.demo679.find();

上記のクエリを実行すると、次のような出力が得られます。

{ "_id" : ObjectId("5ea442cf04263e90dac943fd"), "id" : 1, "details" : [
    { "CountryName" : "US", "information" :  [
       { "Name" : "Chris", "FirstName" : "Name=Chris" },
       { "Name" : "Bob", "FirstName" : "Name=Bob" }
    ] },
    { "CountryName" : "UK", "information" : [
       { "Name" : "Robert", "FirstName" : "Name=Robert" },
       { "Name" : "Sam", "FirstName" : "Name=Sam" }
    ] } 
] }

3. ネストされた配列から要素を削除するクエリ

それでは、サブ配列の中のサブ配列から要素をプル(削除)するクエリを見ていきましょう。ここでは、「US」の information 配列から「Bob」のデータを削除します。

> db.demo679.update(
...     { "details.CountryName":"US" },
...     { $pull: { 'details.$.information': { "Name" : "Bob", "FirstName" : "Name=Bob" } } }
... );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

このクエリのポイントは以下の2点です。

  • 検索条件 { "details.CountryName": "US" } によって、更新対象のドキュメントと親配列(details)内の該当要素が特定されます。
  • パス details.$.information の「$」は、条件に一致した配列要素の位置を自動的に参照する位置指定演算子です。これにより、どのインデックスにあるかを事前に知らなくても更新が可能になります。

実行結果の "nModified" : 1 から、1件のドキュメントが正常に更新されたことが確認できます。

4. 削除後のドキュメントの確認

もう一度 find() メソッドを実行し、要素が正しく削除されたかどうかを確認しましょう。

> db.demo679.find().pretty();

実行結果は以下の通りです。

{
    "_id" : ObjectId("5ea442cf04263e90dac943fd"),
    "id" : 1,
    "details" : [
       {
          "CountryName" : "US",
          "information" : [
             {
                "Name" : "Chris",
                "FirstName" : "Name=Chris"
             }
          ]
       },
       {
          "CountryName" : "UK",
          "information" : [
             {
                "Name" : "Robert",
                "FirstName" : "Name=Robert"
             },
             {
                "Name" : "Sam",
                "FirstName" : "Name=Sam"
             }
          ]
       }
    ]
}

出力を見ると、「US」の information 配列から「Bob」の要素だけが削除され、「Chris」のみが残っていることがわかります。「UK」側のデータには影響が出ていない点にも注目してください。

まとめ

MongoDBでネストされた配列から要素を削除するには、$pull 演算子と位置指定演算子「$」を組み合わせるのが基本です。親配列を一意に特定できる条件をクエリに含めることで、意図した場所のサブ配列だけを安全に操作できます。複雑なドキュメント構造を扱う際には、ぜひこの手法を活用してみてください。

  1. MongoDBでJSON配列の内部要素にアクセスする方法|ドット記法の使い方を解説

    MongoDBでJSON配列の内部要素にアクセスするには、ドット記法(dot notation)を使用します。本記事では、実際にコレクションを作成し、ネストされた配列内のフィールドを検索する具体的な手順を、サンプルコードと実行結果とともに解説します。 サンプルデータの作成 まず、insert()メソッドを使って、ネストされた構造を持つドキュメントを含むコレクションを作成しましょう。 > db.demo687.insert({CountryName:US, ... info: ... { ... id:101, ... details: ... [ ... { ...   &n

  2. MongoDBでネストしたサブドキュメントをフィルタリングする方法(aggregateと$unwind活用)

    MongoDBでは、配列の中にさらに配列(サブドキュメント)がネストしている構造を持つドキュメントから、特定の条件に合致する要素だけを抽出したいケースがあります。このような場合、aggregate()メソッドと$unwind演算子を組み合わせることで実現できます。本記事では、実際のコード例を使いながら、ネストしたサブドキュメントのフィルタリング手順を解説します。サンプルコレクションの作成まず、ネストしたサブドキュメントを含むドキュメントを挿入して、コレクションを作成しましょう。> db.demo583.insert([ ... { ... details1 : [