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

$lookup演算子を使用した複数の結合条件

    $lookupを使用して複数の結合条件を実行できます バージョン3.6以降の集約パイプライン演算子。

    letを使用して、フィールドの値を変数に割り当てる必要があります オプションのフィールド。次に、pipelineでこれらの変数にアクセスします コレクションで実行するパイプラインを指定するフィールドステージ。

    $matchに注意してください ステージでは、$exprを使用します フィールドの値を比較するための評価クエリ演算子。

    パイプラインの最後の段階は$replaceRootです $lookupを単純にマージする集約パイプラインステージ $$ROOTの一部を含む結果 $mergeObjectsを使用したドキュメント オペレーター。

    db.collection2.aggregate([
           {
              $lookup: {
                 from: "collection1",
                 let: {
                    firstUser: "$user1",
                    secondUser: "$user2"
                 },
                 pipeline: [
                    {
                       $match: {
                          $expr: {
                             $and: [
                                {
                                   $eq: [
                                      "$user1",
                                      "$$firstUser"
                                   ]
                                },
                                {
                                   $eq: [
                                      "$user2",
                                      "$$secondUser"
                                   ]
                                }
                             ]
                          }
                       }
                    }
                 ],
                 as: "result"
              }
           },
           {
              $replaceRoot: {
                 newRoot: {
                    $mergeObjects:[
                       {
                          $arrayElemAt: [
                             "$result",
                             0
                          ]
                       },
                       {
                          percent1: "$$ROOT.percent1"
                       }
                    ]
                 }
              }
           }
        ]
    )
    

    このパイプラインは、次のようなものを生成します:

    {
        "_id" : ObjectId("59e1ad7d36f42d8960c06022"),
        "user1" : 1,
        "user2" : 2,
        "percent" : 0.3,
        "percent1" : 0.56
    }
    

    バージョン3.6以降を使用していない場合は、最初にフィールドの1つ(たとえば「user1」)を使用して参加し、そこから$unwindを使用して一致するドキュメントの配列を巻き戻します。 集約パイプライン演算子。パイプラインの次の段階は$redactです $$KEEPを使用して、「joined」コレクションの「user2」の値と入力ドキュメントが等しくないドキュメントを除外するステージ および$$PRUNE システム変数。その後、$projectでドキュメントの形状を変更できます ステージ。

    db.collection1.aggregate([
        { "$lookup": { 
            "from": "collection2", 
            "localField": "user1", 
            "foreignField": "user1", 
            "as": "collection2_doc"
        }}, 
        { "$unwind": "$collection2_doc" },
        { "$redact": { 
            "$cond": [
                { "$eq": [ "$user2", "$collection2_doc.user2" ] }, 
                "$$KEEP", 
                "$$PRUNE"
            ]
        }}, 
        { "$project": { 
            "user1": 1, 
            "user2": 1, 
            "percent1": "$percent", 
            "percent2": "$collection2_doc.percent"
        }}
    ])
    

    生成するもの:

    {
        "_id" : ObjectId("572daa87cc52a841bb292beb"),
        "user1" : 1,
        "user2" : 2,
        "percent1" : 0.56,
        "percent2" : 0.3
    }
    

    コレクション内のドキュメントが同じ構造であり、この操作を頻繁に実行していることに気付いた場合は、2つのコレクションを1つにマージするか、それらのコレクション内のドキュメントを新しいコレクションに挿入することを検討する必要があります。

    db.collection3.insertMany(
        db.collection1.find({}, {"_id": 0})
        .toArray()
        .concat(db.collection2.find({}, {"_id": 0}).toArray())
    )
    

    次に、$group 「user1」と「user2」によるドキュメント

    db.collection3.aggregate([
        { "$group": {
            "_id": { "user1": "$user1", "user2": "$user2" }, 
            "percent": { "$push": "$percent" }
        }}
    ])
    

    これにより、次のようになります:

    { "_id" : { "user1" : 1, "user2" : 2 }, "percent" : [ 0.56, 0.3 ] }
    


    1. Rails3.2でMongoidを使用するときにdatabase.ymlを削除する

    2. 9つの新しいMongoDB機能–MongoDBで習得することを学ぶ必要があります

    3. 変更ストリームを使用して本番環境でMongoDBを実行するためのヒント

    4. MongoDBサンプルオペレーター