MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Mongo cách tra cứu $ với DBRef

Trên thực tế, câu trả lời khác là sai. Có thể thực hiện tra cứu trường DBref trong trình tổng hợp của bạn và bạn không cần lập bản đồ cho điều đó.

Giải pháp

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

kết quả

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

Giải thích ngắn gọn

Lặp qua các DBRef với $ map, ngắt mỗi DBref thành một mảng, chỉ giữ lại trường $ id, sau đó loại bỏ định dạng k:v với $$ this.v, chỉ giữ lại ObjectId và loại bỏ tất cả phần còn lại. Bây giờ bạn có thể tra cứu trên ObjectId.

Giải thích từng bước

Trong bộ tổng hợp, loại DBRef BSON có thể được xử lý giống như một đối tượng, với hai hoặc ba trường (ref, id và db).

Nếu bạn làm như vậy:

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

    },

])

Đây là kết quả:

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

Khi bạn đã chuyển đổi một dbref thành một mảng, bạn có thể loại bỏ các trường vô dụng bằng cách chỉ truy vấn giá trị tại chỉ mục 1, như sau:

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

    },

])

kết quả:

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

Sau đó, cuối cùng bạn có thể đạt đến giá trị bạn muốn bằng cách trỏ tới "$ myvalue.v", giống như thế này

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

])

kết quả:

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

Rõ ràng, trong một quy trình thông thường, bạn không cần tất cả các bước thừa này, bằng cách sử dụng $ map lồng nhau, bạn có thể đạt được cùng một kết quả chỉ trong một lần:

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

            }
    }, 

])

kết quả:

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

Tôi hy vọng lời giải thích đủ rõ ràng, nếu không, hãy hỏi.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Nhận _id của một tài liệu được chèn trong MongoDB?

  2. Trường hợp cho chỉ số băm MongoDB

  3. Những ký tự nào KHÔNG được phép trong tên trường MongoDB?

  4. So sánh ngày trong mongodb

  5. Xuất kết quả khung tổng hợp mongodb sang một bộ sưu tập mới