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

MongoDBRefで$lookupする方法

    実際、他の答えは間違っています。アグリゲーター内のDBrefフィールドでルックアップを実行することは可能であり、そのためにmapreduceは必要ありません。

    ソリューション

    db.A.aggregate([
    {
        $project: { 
            B_fk: {
              $map: { 
                 input: { 
                      $map: {
                          input:"$bid",
                          in: {
                               $arrayElemAt: [{$objectToArray: "$$this"}, 1]
                          },
                      }
                 },
                 in: "$$this.v"}},
            }
    }, 
    {
        $lookup: {
            from:"B", 
            localField:"B_fk",
            foreignField:"_id", 
            as:"B"
        }
    }
    ])
    

    結果

    {
        "_id" : ObjectId("59bb79df1e9c00162566f581"),
        "B_fk" : null,
        "B" : [ ]
    },
    {
        "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
        "B_fk" : [
            ObjectId("582abcd85d2dfa67f44127e0"),
            ObjectId("582abcd85d2dfa67f44127e1")
        ],
        "B" : [
            {
                "_id" : ObjectId("582abcd85d2dfa67f44127e0"),
                "status" : NumberInt("1"),
                "seq" : NumberInt("0")
            }
        ]
    }
    

    簡単な説明

    $ mapを使用してDBRefをループし、各DBrefを配列に分割し、$ idフィールドのみを保持してから、$$ this.vを使用してk:v形式を削除し、ObjectIdのみを保持し、残りをすべて削除します。これで、ObjectIdを検索できます。

    ステップバイステップの説明

    アグリゲーター内では、DBRef BSONタイプは、2つまたは3つのフィールド(ref、id、およびdb)を持つオブジェクトのように処理できます。

    行う場合:

    db.A.aggregate([
        {
            $project: { 
                First_DBref_as_array: {$objectToArray:{$arrayElemAt:["$bid",0]}},
                Second_DBref_as_array: {$objectToArray:{$arrayElemAt:["$bid",1]}},
                }
    
        },
    
    ])
    

    結果は次のとおりです。

    {
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
    "First_DBref_as_array : [
        {
            "k" : "$ref",
            "v" : "B"
        },
        {
            "k" : "$id",
            "v" : ObjectId("582abcd85d2dfa67f44127e0")
        }
    ],
    "Second_DBref_as_array" : [
        {
            "k" : "$ref",
            "v" : "B"
        },
        {
            "k" : "$id",
            "v" : ObjectId("582abcd85d2dfa67f44127e0")
        }
    ]
    }
    

    dbrefを配列に変換したら、次のようにインデックス1の値のみをクエリすることで、役に立たないフィールドを取り除くことができます。

    db.A.aggregate([
        {
            $project: { 
                First_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
                Second_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
                }
    
        },
    
    ])
    

    結果:

    {
        "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
        "First_DBref_as_array" : {
            "k" : "$id",
            "v" : ObjectId("582abcd85d2dfa67f44127e0")
        },
        "Second_DBref_as_array" : {
            "k" : "$id",
            "v" : ObjectId("582abcd85d2dfa67f44127e0")
        }
    }
    

    次に、このように「$ myvalue.v」をポイントすることで、最終的に目的の値に到達できます

    db.A.aggregate([
        {
            $project: { 
                first_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
                second_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
                }
    
        },
        {
            $project: {
                first_DBref_as_ObjectId: "$first_DBref_as_array.v",
                second_DBref_as_ObjectId: "$second_DBref_as_array.v"
            }
        }
    
    ])
    

    結果:

    {
        "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
        "first_DBref_as_ObjectId" : ObjectId("582abcd85d2dfa67f44127e0"),
        "second_DBref_as_ObjectId" : ObjectId("582abcd85d2dfa67f44127e0")
    }
    

    明らかに、通常のパイプラインでは、ネストされた$ mapを使用して、これらの冗長な手順をすべて必要とせず、一度に同じ結果を得ることができます:

    db.A.aggregate([
        {
            $project: { 
                B_fk: { $map : {input: { $map: {    input:"$bid",
                                        in: { $arrayElemAt: [{$objectToArray: "$$this"}, 1 ]}, } },
                                in: "$$this.v"}},
    
                }
        }, 
    
    ])
    

    結果:

    {
        "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
        "B_fk" : [
            ObjectId("582abcd85d2dfa67f44127e0"),
            ObjectId("582abcd85d2dfa67f44127e1")
        ]
    }
    

    遠慮なく質問しても、説明が十分に明確であることを願っています。



    1. Node.jsの自己署名証明書を使用したMongoDBSSL

    2. HBaseACLのレンジャーポリシーへの変換

    3. MongoDB $ year

    4. 接続の管理