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

Agregat $lookup tidak mengembalikan elemen urutan array asli

Ini adalah "sesuai desain" dari $lookup penerapan. Apa sebenarnya terjadi "di bawah tenda" adalah MongoDB internal mengonversi argumen di $lookup ke ekspresif yang baru format menggunakan $expr dan $in . Bahkan dalam versi sebelum ekspresif ini formulir diimplementasikan, mekanisme internal untuk "array nilai" benar-benar sama.

Solusinya di sini adalah menyimpan salinan larik asli sebagai referensi untuk menyusun ulang "bergabung" item:

collection.aggregate([
  {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
  {"$lookup": {
    "from": "collection2",
    "let": { "classIds": "$Classes.ID" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": [ "$_id", "$$classIds" ] }
      }},
      { "$addFields": {
        "sort": {
          "$indexOfArray": [ "$$classIds", "$_id" ]
        }
      }},
      { "$sort": { "sort": 1 } },
      { "$addFields": { "sort": "$$REMOVE" }}
    ],
    "as": "results"
  }}
])

Atau dengan $lookup legacy yang lama penggunaan:

collection.aggregate([
  {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
  {"$lookup": {
    "from": "collection2",
    "localField": "Classes.ID",
    "foreignField": "_id",
    "as": "results"
  }},
  { "$unwind": "$results" },
  { "$addFields": {
    "sort": {
      "$indexOfArray": [ "$Classes.ID", "$results._id" ]
    }
  }},
  { "$sort": { "_id": 1, "sort": 1 } },
  { "$group": {
    "_id": "$_id",
    "Name": { "$first": "$Name" },
    "Classes": { "$first": "$Classes" },
    "results": { "$push": "$results" }
  }}
])

Kedua varian menghasilkan output yang sama:

{
        "_id" : ObjectId("5c781752176c512f180048e3"),
        "Name" : "Pedro",
        "Classes" : [
                {
                        "ID" : ObjectId("5c7af2b2f6f6e47c9060d7ce")
                },
                {
                        "ID" : ObjectId("5c7af2bcf6f6e47c9060d7cf")
                },
                {
                        "ID" : ObjectId("5c7af2aaf6f6e47c9060d7cd")
                }
        ],
        "results" : [
                {
                        "_id" : ObjectId("5c7af2b2f6f6e47c9060d7ce"),
                        "variable1" : "B"
                },
                {
                        "_id" : ObjectId("5c7af2bcf6f6e47c9060d7cf"),
                        "variable1" : "C"
                },
                {
                        "_id" : ObjectId("5c7af2aaf6f6e47c9060d7cd"),
                        "variable1" : "A"
                }
        ]
}

Konsep umum adalah menggunakan $indexOfArray dibandingkan dengan _id nilai dari "bergabung" konten untuk menemukan "indeks" posisi dalam larik sumber asli dari "$Classes.ID" . $lookup different yang berbeda varian sintaks memiliki pendekatan yang berbeda tentang cara Anda mengakses salinan dan bagaimana Anda pada dasarnya merekonstruksi.

$sort tentu saja mengatur urutan dokumen yang sebenarnya, baik yang di dalam pemrosesan pipa untuk bentuk ekspresif, atau melalui dokumen terbuka $unwind . Tempat Anda menggunakan $unwind Anda kemudian akan $group kembali ke formulir dokumen asli.

CATATAN :Contoh penggunaan di sini bergantung pada MongoDB 3.4 untuk $indexOfArray setidaknya dan $$REMOVE sejajar dengan MongoDB 3.6 seperti halnya ekspresif $lookup .

Ada pendekatan lain untuk mengurutkan ulang array untuk rilis sebelumnya, tetapi ini ditunjukkan secara lebih rinci pada pesanan jaminan klausa $in dari Apakah MongoDB. Secara realistis, minimum yang harus Anda jalankan saat ini sebagai versi produksi MongoDB adalah rilis 3.4.

Lihat Kebijakan Dukungan di bawah Server MongoDB untuk detail lengkap tentang rilis yang didukung dan tanggal akhir.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Dasar-dasar Menyebarkan Kumpulan Replika MongoDB dan Pecahan Menggunakan Wayang

  2. Panduan untuk Memasang di MongoDB

  3. Catatan acak dari MongoDB

  4. Bagaimana cara mengatasi kurangnya transaksi di MongoDB?

  5. Isi array bersarang di luwak