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

$lookup pada ObjectId dalam array

Pembaruan 2017

$lookup sekarang dapat langsung menggunakan array sebagai bidang lokal. $unwind tidak diperlukan lagi.

Jawaban lama

$lookup tahap pipa agregasi tidak akan bekerja secara langsung dengan array. Maksud utama dari desain ini adalah untuk "gabung kiri" sebagai jenis gabungan "satu ke banyak" (atau benar-benar "pencarian") pada kemungkinan data terkait. Tapi nilainya dimaksudkan untuk menjadi tunggal dan bukan array.

Oleh karena itu Anda harus "menormalkan kembali" konten terlebih dahulu sebelum melakukan $lookup operasi agar ini bekerja. Dan itu berarti menggunakan $unwind :

db.orders.aggregate([
    // Unwind the source
    { "$unwind": "$products" },
    // Do the lookup matching
    { "$lookup": {
       "from": "products",
       "localField": "products",
       "foreignField": "_id",
       "as": "productObjects"
    }},
    // Unwind the result arrays ( likely one or none )
    { "$unwind": "$productObjects" },
    // Group back to arrays
    { "$group": {
        "_id": "$_id",
        "products": { "$push": "$products" },
        "productObjects": { "$push": "$productObjects" }
    }}
])

Setelah $lookup cocok dengan setiap anggota larik, hasilnya adalah larik itu sendiri, jadi Anda $unwind lagi dan $group ke $push array baru untuk hasil akhir.

Perhatikan bahwa setiap kecocokan "gabung kiri" yang tidak ditemukan akan membuat larik kosong untuk "productObjects" pada produk yang diberikan dan dengan demikian meniadakan dokumen untuk elemen "produk" saat $unwind kedua disebut.

Meskipun aplikasi langsung ke array akan menyenangkan, ini hanya cara kerjanya saat ini dengan mencocokkan nilai tunggal ke banyak kemungkinan.

Sebagai $lookup pada dasarnya sangat baru, saat ini berfungsi seperti biasa bagi mereka yang akrab dengan luwak sebagai "versi orang miskin" dari .populate() metode yang ditawarkan di sana. Perbedaannya adalah $lookup menawarkan pemrosesan "sisi server" dari "gabung" sebagai lawan dari pada klien dan bahwa beberapa "kematangan" di $lookup saat ini kurang dari apa .populate() menawarkan ( seperti interpolasi pencarian langsung pada array ).

Ini sebenarnya adalah masalah yang ditetapkan untuk peningkatan SERVER-22881, jadi dengan sedikit keberuntungan ini akan mencapai rilis berikutnya atau segera setelahnya.

Sebagai prinsip desain, struktur Anda saat ini tidak baik atau buruk, tetapi hanya dikenakan biaya tambahan saat membuat "gabungan" apa pun. Dengan demikian, prinsip dasar MongoDB di awal berlaku, di mana jika Anda "bisa" hidup dengan data "pra-bergabung" dalam satu koleksi, maka yang terbaik adalah melakukannya.

Satu hal lagi yang dapat dikatakan tentang $lookup sebagai prinsip umum, adalah bahwa maksud dari "bergabung" di sini adalah untuk bekerja sebaliknya daripada yang ditunjukkan di sini. Jadi, daripada menyimpan "id terkait" dari dokumen lain di dalam dokumen "induk", prinsip umum yang paling berhasil adalah jika "dokumen terkait" berisi referensi ke "induk".

Jadi $lookup dapat dikatakan "bekerja paling baik" dengan "desain hubungan" yang merupakan kebalikan dari bagaimana sesuatu seperti luwak .populate() melakukan itu sisi klien bergabung. Dengan mengidentifikasi "satu" di dalam setiap "banyak", maka Anda cukup menarik item terkait tanpa perlu $unwind array terlebih dahulu.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. php mongodb temukan entri ke-n dalam koleksi

  2. Bagaimana Membandingkan MongoDB dengan YCSB?

  3. 7 Cara untuk Memeriksa Versi MongoDB Anda

  4. Memperbarui jalur 'x' akan membuat konflik di 'x'

  5. Mongodb menemukan hasil yang dibuat berdasarkan tanggal hari ini