MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Mongo cara $lookup dengan DBRef

Sebenarnya, jawaban yang lain salah. Dimungkinkan untuk melakukan pencarian pada bidang DBref dalam agregator Anda, dan Anda tidak perlu mapreduce untuk itu.

Solusi

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

hasil

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

Penjelasan Singkat

Ulangi DBRefs dengan $map, pisahkan setiap DBref ke dalam array, pertahankan hanya bidang $id, lalu hapus format k:v dengan $$this.v, simpan hanya ObjectId dan hapus sisanya. Anda sekarang dapat mencari di ObjectId.

Penjelasan Langkah demi Langkah

Di dalam agregator, tipe DBRef BSON dapat ditangani seperti objek, dengan dua atau tiga bidang (ref, id, dan db).

Jika Anda melakukannya:

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

    },

])

Ini hasilnya:

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

Setelah Anda mengubah dbref menjadi array, Anda dapat membuang kolom yang tidak berguna dengan hanya menanyakan nilai pada indeks 1, seperti ini:

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

    },

])

hasil:

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

Kemudian Anda akhirnya bisa mendapatkan nilai yang Anda inginkan dengan menunjuk ke "$myvalue.v", seperti ini

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

])

hasil:

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

Jelas, dalam pipeline normal, Anda tidak memerlukan semua langkah yang berlebihan ini, menggunakan $map bersarang, Anda bisa mendapatkan hasil yang sama dalam sekali jalan :

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

            }
    }, 

])

hasil:

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

Saya harap penjelasannya cukup jelas, jika tidak, jangan ragu untuk bertanya.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana cara mengaktifkan bidang boolean dalam satu dokumen dengan operasi atom?

  2. MongoDB:pembaruan tanpa syarat?

  3. Kelas 'MongoClient' tidak ditemukan

  4. Pertimbangan untuk Mengelola MongoDB

  5. Cara Memeriksa Tipe Data Kolom di SQL