복붙노트

[MONGODB] 몽고에서는 DBRef으로 조회 $합니다

MONGODB

몽고에서는 DBRef으로 조회 $합니다

나는 문제가 (/ (ㄒ O ㄒ) / ~). 그 수집 A는 가정

{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"), 
    "bid" : [
        DBRef("B", ObjectId("582abcd85d2dfa67f44127e0")),
        DBRef("B", ObjectId("582abcd85d2dfa67f44127e1"))
    ]
}

및 컬렉션 B :

{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e0"),  
    "status" : NumberInt(1), 
    "seq" : NumberInt(0)
},
{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"), 
    "status" : NumberInt(1), 
    "seq" : NumberInt(0)
} 

나는 '입찰'을 검색 $하는 방법을 모르겠어요. 나는 시도

db.A.aggregate(
    [
        {$unwind: {path: "$bid"}},
        {$lookup: {from: "B", localField: "bid", foreignField: "_id", as: "bs"}},
    ]
) 

db.A.aggregate(
    [
        {$unwind: {path: "$bid"}},
        {$lookup: {from: "B", localField: "bid.$id", foreignField: "_id", as: "bs"}},
    ]
)

그러나 그것은 작동하지 않습니다. 아무도 도와 드릴까요? 감사.

해결법

  1. ==============================

    1.사실, 다른 대답은 잘못된 것입니다. 당신의 어 그리 게이터 내에서 DBref 필드에 조회를 할 수 있습니다, 당신은 그것을 위해 맵리 듀스가 필요하지 않습니다.

    사실, 다른 대답은 잘못된 것입니다. 당신의 어 그리 게이터 내에서 DBref 필드에 조회를 할 수 있습니다, 당신은 그것을 위해 맵리 듀스가 필요하지 않습니다.

    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")
            }
        ]
    }
    

    $지도와 DBREFS을 통해 루프, 배열로 각 DBref 휴식 만 $ ID 필드를 유지 한 후 K 제거 : V 형식을 $$ this.v으로 만 ObjectId가를 유지하고 모두에게 나머지를 제거. 이제 ObjectId가에 조회 할 수 있습니다.

    게이터 내에서, DBRef BSON 유형은 두 개 또는 세 개의 필드 (참조, 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")
    }
    

    물론, 일반 파이프 라인, 중첩 $ 맵을 사용하여 모든 중복 단계가 필요하지 않습니다, 당신은 한 번에 동일한 결과를 얻을 수 있습니다 :

    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")
        ]
    }
    

    문의 주시기하지 않을 경우 나는 설명이 명확 충분 바랍니다.

  2. ==============================

    2.MongoDB를 3.4로, 이는 가능하지 않다. 당신은 $ 일치하는 단계를 제외하고 집계 파이프 라인에서 DBRef을 사용할 수 없습니다.

    MongoDB를 3.4로, 이는 가능하지 않다. 당신은 $ 일치하는 단계를 제외하고 집계 파이프 라인에서 DBRef을 사용할 수 없습니다.

    난 강력하게 당신이 DBRef 없애 수동 참조로 전환하는 것이 좋습니다. 당신이 정말로 DBRef을 유지해야하는 경우, 여기 (못생긴) 솔루션입니다 :

    첫째, DBREFS는 맵리 듀스를 사용하여 IDS로 대체됩니다 "C"라는 새 컬렉션을 만들 :

    db.A.mapReduce(
        function() {
            var key = this._id; 
            var value = [];  
            for ( var index = 0; index < this.bid.length; index++){
               value.push(this.bid[index].$id); 
            }
            emit(key, value); 
        },
        function(key,values) {
            return  values;
        },
        {
            "query": {},
            "out": "C" 
        }
    )
    

    다음, 새로운 "C"컬렉션 당신의 집계 쿼리를 실행합니다 :

    db.C.aggregate([
       {
          $unwind:"$value"
       },
       {
          $lookup:{
             from:"B",
             localField:"value",
             foreignField:"_id",
             as:"bs"
          }
       }
    ]);
    

    산출:

        {
           "_id":ObjectId("582abcd85d2dfa67f44127e1"),
           "value":ObjectId("582abcd85d2dfa67f44127e0"),
           "bs":[
              {
                 "_id":ObjectId("582abcd85d2dfa67f44127e0"),
                 "status":1,
                 "seq":0
              }
           ]
        }{
           "_id":ObjectId("582abcd85d2dfa67f44127e1"),
           "value":ObjectId("582abcd85d2dfa67f44127e1"),
           "bs":[
              {
                 "_id":ObjectId("582abcd85d2dfa67f44127e1"),
                 "status":1,
                 "seq":0
              }
           ]
        }
    
  3. from https://stackoverflow.com/questions/40622714/mongo-how-to-lookup-with-dbref by cc-by-sa and MIT license