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

urutkan berdasarkan nilai objek yang disematkan di Mongodb

Jika Anda perlu menghitung sesuatu seperti ini saat runtime, dengan konten "difilter" dari array yang menentukan urutan pengurutan, maka Anda sebaiknya melakukan sesuatu dengan .aggregate() untuk membentuk kembali dan menentukan nilai sortir seperti ini:

db.collection.aggregate([
    // Pre-filter the array elements
    { "$project": {
        "tags": 1,
        "score": {
            "$setDifference": [
                { "$map": {
                    "input": "$tags",
                    "as": "tag",
                    "in": {
                        "$cond": [
                            { "$eq": [ "$$el.id", "t1" ] },
                            "$$el.score",
                            false
                        ]
                    }
                }},
                [false]
            ]
        }
    }},
    // Unwind to denormalize
    { "$unwind": "$score" },
    // Group back the "max" score
    { "$group": {
        "_id": "$_id",
        "tags": { "$first": "$tags" },
        "score": { "$max": "$score" }
    }},
    // Sort descending by score
    { "$sort": { "score": -1 } }
])

Di mana bagian pertama dari pipa digunakan untuk "memfilter" konten array (serta menjaga bidang asli) hanya untuk nilai "skor" di mana id sama dengan "t1". Ini dilakukan dengan memproses $map yang menerapkan ketentuan untuk setiap elemen melalui $cond untuk menentukan apakah akan mengembalikan "skor" untuk elemen tersebut atau false .

$setDifference operasi melakukan perbandingan dengan larik elemen tunggal [false] yang secara efektif menghapus false nilai yang dikembalikan dari $map . Sebagai "set", ini juga menghapus entri duplikat, tetapi untuk tujuan pengurutan di sini ini adalah hal yang baik.

Dengan array dikurangi dan dibentuk kembali ke nilai yang Anda proses $unwind siap untuk tahap selanjutnya untuk menangani nilai-nilai sebagai elemen individu. $group stage pada dasarnya berlaku $max pada "skor" untuk mengembalikan nilai tertinggi yang terkandung dalam hasil yang difilter.

Maka tinggal menerapkan $sort pada nilai yang ditentukan untuk memesan dokumen. Tentu saja jika Anda menginginkan ini sebaliknya, gunakan $min dan urutkan dalam urutan menaik.

Tentu saja tambahkan $match tahap ke awal jika yang Anda inginkan hanyalah dokumen yang benar-benar berisi nilai "t1" untuk id dalam tag. Tetapi bagian itu paling tidak relevan dengan penyortiran pada hasil yang difilter yang ingin Anda capai.

Alternatif untuk menghitung adalah melakukan semuanya saat Anda menulis entri ke larik di dokumen. Agak berantakan, tapi kira-kira seperti ini:

db.collection.update(
    { "_id": docId },
    {
        "$push": { "tags": { "id": "t1", "score": 60 } },
        "$max": { "maxt1score": 60 },
        "$min": { "mint1score": 60 }
    }
)

Berikut $max operator pembaruan hanya menetapkan nilai untuk bidang yang ditentukan jika nilai baru lebih besar dari nilai yang ada atau jika tidak, properti belum ada. Kasus sebaliknya berlaku untuk $min , dimana hanya jika kurang dari itu akan diganti dengan nilai baru.

Ini tentu saja akan berdampak pada penambahan berbagai properti tambahan ke dokumen, tetapi hasil akhirnya adalah penyortiran yang sangat disederhanakan:

db.collection.find().sort({ "maxt1score": -1 })

Dan itu akan berjalan jauh lebih cepat daripada menghitung dengan pipeline agregasi.

Jadi pertimbangkan prinsip-prinsip desain. Data terstruktur dalam larik di mana Anda ingin menyaring dan memasangkan hasil untuk pengurutan berarti menghitung saat run-time untuk menentukan nilai mana yang akan diurutkan. Menambahkan properti tambahan ke dokumen di .update() berarti Anda cukup mereferensikan properti tersebut untuk menyortir hasil secara langsung.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Setelah meteor bundle, node.js MENDENGARKAN tetapi tidak muncul di localhost

  2. Hapus catatan lama di mongodb berdasarkan Bulan

  3. Mendapatkan pengecualian saat melakukan block() pada objek Mono yang saya dapatkan kembali dari objek ReactiveMongoRepository

  4. Pencarian Kabur dengan Mongodb?

  5. MongoDB :Kerangka kerja agregasi :Dapatkan dokumen bertanggal terakhir per ID pengelompokan