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

集計$lookupは、要素の元の配列順序を返しません

    これは、$lookupの「設計による」ものです。 実装。 実際に 「内部」で発生します MongoDB internal $lookupの引数を変換します 新しい表現力のある $exprを使用したフォーマット および$in 。この表現力のある以前のバージョンでも フォームが実装され、「値の配列」の内部メカニズム 本当にほとんど同じでした。

    ここでの解決策は、 "joined"を並べ替えるための参照として元の配列のコピーを維持することです。 アイテム:

    collection.aggregate([
      {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
      {"$lookup": {
        "from": "collection2",
        "let": { "classIds": "$Classes.ID" },
        "pipeline": [
          { "$match": {
            "$expr": { "$in": [ "$_id", "$$classIds" ] }
          }},
          { "$addFields": {
            "sort": {
              "$indexOfArray": [ "$$classIds", "$_id" ]
            }
          }},
          { "$sort": { "sort": 1 } },
          { "$addFields": { "sort": "$$REMOVE" }}
        ],
        "as": "results"
      }}
    ])
    

    または、レガシーの$lookup 使用法:

    collection.aggregate([
      {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
      {"$lookup": {
        "from": "collection2",
        "localField": "Classes.ID",
        "foreignField": "_id",
        "as": "results"
      }},
      { "$unwind": "$results" },
      { "$addFields": {
        "sort": {
          "$indexOfArray": [ "$Classes.ID", "$results._id" ]
        }
      }},
      { "$sort": { "_id": 1, "sort": 1 } },
      { "$group": {
        "_id": "$_id",
        "Name": { "$first": "$Name" },
        "Classes": { "$first": "$Classes" },
        "results": { "$push": "$results" }
      }}
    ])
    

    どちらのバリアントも同じ出力を生成します:

    {
            "_id" : ObjectId("5c781752176c512f180048e3"),
            "Name" : "Pedro",
            "Classes" : [
                    {
                            "ID" : ObjectId("5c7af2b2f6f6e47c9060d7ce")
                    },
                    {
                            "ID" : ObjectId("5c7af2bcf6f6e47c9060d7cf")
                    },
                    {
                            "ID" : ObjectId("5c7af2aaf6f6e47c9060d7cd")
                    }
            ],
            "results" : [
                    {
                            "_id" : ObjectId("5c7af2b2f6f6e47c9060d7ce"),
                            "variable1" : "B"
                    },
                    {
                            "_id" : ObjectId("5c7af2bcf6f6e47c9060d7cf"),
                            "variable1" : "C"
                    },
                    {
                            "_id" : ObjectId("5c7af2aaf6f6e47c9060d7cd"),
                            "variable1" : "A"
                    }
            ]
    }
    

    $indexOfArrayを使用することの一般的な概念 _idとの比較 "joined"からの値 "インデックス"を見つけるためのコンテンツ "$Classes.ID"からの元のソース配列内の位置 。別の$lookup 構文バリアントには、このコピーへのアクセス方法に対するさまざまなアプローチがあります。 基本的にどのように再構築するか。

    $sort もちろん、実際のドキュメントの順序を設定します。パイプライン処理内 表現形式の場合、または$unwindの公開ドキュメントを介して 。 $unwindを使用した場所 次に、$group 元のドキュメントフォームに戻ります。

    :ここでの使用例は、$indexOfArrayのMongoDB3.4に依存しています 少なくとも、$$REMOVE 表現力のあるのようにMongoDB3.6と連携します $lookup

    以前のリリースの配列を並べ替える方法は他にもありますが、これらは、DoesMongoDBの$in句が順序を保証するかについて詳しく説明されています。現実的には、MongoDBの本番バージョンとして現在実行している必要のある最低限のものは3.4リリースです。

    サポートポリシーをご覧ください MongoDBサーバーの下 サポートされているリリースと終了日の詳細については、




    1. ホストマシンからDockerコンテナで実行されているRedisに接続する

    2. Mongodbアグリゲーション$group、配列の長さを制限

    3. Redisクラスターでパターンに一致するキーを削除する方法

    4. MongoDB:配列要素のプロパティの一意のインデックス