sql >> データベース >  >> NoSQL >> MongoDB

Double NestedArrayMongoDBで検索

    最も単純な意味では、これはMongoDBで使用される「ドット表記」の基本的な形式に従います。これは、値と一致する限り、内部配列メンバーがどの配列メンバーにあるかに関係なく機能します。

    db.mycollection.find({
        "someArray.someNestedArray.name": "value"
    })
    

    これは「単一フィールド」の値には問題ありません。複数のフィールドを照合するには、$elemMatchを使用します。 :

    db.mycollection.find({
        "someArray": { 
            "$elemMatch": {
                "name": "name1",
                "someNestedArray": {
                    "$elemMatch": {
                        "name": "value",
                        "otherField": 1
                    }
                }
            }
        }
    })
    

    これは、値と一致する「パス」にフィールドを持つ何かを含むドキュメントと一致します。結果を「一致およびフィルタリング」して、一致した要素のみが返されるようにする場合、引用されているように、位置演算子の射影ではこれは不可能です。

    ネストされた配列

    $プレースホルダーの置換は単一の値であるため、他の配列内にネストされた配列をトラバースするクエリなど、複数の配列をトラバースするクエリには、位置$演算子を使用できません。

    最新のMongoDB

    これを行うには、$filterを適用します および$map ここ。 $map 「フィルタリング」の結果として「内部」配列が変更される可能性があり、「外部」配列はもちろん「内部」からすべての要素が削除されたときの条件と一致しないため、これは本当に必要です。

    再び、各配列内で一致する複数のプロパティを実際に持つ例に従います。

    db.mycollection.aggregate([
      { "$match": {
        "someArray": {
          "$elemMatch": {
             "name": "name1",
             "someNestedArray": {
               "$elemMatch": {
                 "name": "value",
                 "otherField": 1
               }
             }
           }
        }
      }},
      { "$addFields": {
        "someArray": {
          "$filter": {
            "input": {
              "$map": {
                "input": "$someArray",
                "as": "sa",
                "in": {
                  "name": "$$sa.name",
                  "someNestedArray": {
                    "$filter": {
                      "input": "$$sa.someNestedArray",
                      "as": "sn",
                      "cond": {
                        "$and": [
                          { "$eq": [ "$$sn.name", "value" ] },
                          { "$eq": [ "$$sn.otherField", 1 ] }
                        ]
                      }
                    }
                  }             
                }
              },
            },
            "as": "sa",
            "cond": {
              "$and": [
                { "$eq": [ "$$sa.name", "name1" ] },
                { "$gt": [ { "$size": "$$sa.someNestedArray" }, 0 ] }
              ]
            }
          }
        }
      }}
    ])
    

    したがって、「外部」配列では、$filter 実際に$sizeを調べます 「内部」配列自体が「フィルタリング」された後の「内部」配列の結果であるため、内部配列全体が実際に注記と一致する場合は、これらの結果を拒否できます。

    古いMongoDB

    一致した要素のみを「投影」するには、.aggregate()が必要です。 方法:

    db.mycollection.aggregate([
        // Match possible documents
        { "$match": {
            "someArray.someNestedArray.name": "value"
        }},
    
        // Unwind each array
        { "$unwind": "$someArray" },
        { "$unwind": "$someArray.someNestedArray" },
    
        // Filter just the matching elements
        { "$match": {
            "someArray.someNestedArray.name": "value"
        }},
    
        // Group to inner array
        { "$group": {
            "_id": { 
                "_id": "$_id", 
                "name": "$someArray.name"
            },
            "someKey": { "$first": "$someKey" },
            "someNestedArray": { "$push": "$someArray.someNestedArray" }
        }},
    
        // Group to outer array
        { "$group": {
            "_id": "$_id._id",
            "someKey": { "$first": "$someKey" },
            "someArray": { "$push": {
                "name": "$_id.name",
                "someNestedArray": "$someNestedArray"
            }}
        }} 
    ])
    

    これにより、ドキュメント内の1つ以上の結果について、ネストされた配列の一致を「フィルタリング」できます。



    1. ノード-マングース3.6-入力されたフィールドでクエリを並べ替える

    2. MongoDBでの地理空間サポート

    3. 1つのコマンドでmongoDBを停止する方法

    4. 一意のアトミックIDジェネレーターとしてのRedis-競合状態を回避するためのWebアプリのスレッドセーフな方法