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

Kueri Mongo untuk mengurutkan berdasarkan jumlah yang berbeda

Ini benar-benar (masih) paling baik ditangani oleh banyak kueri, karena MongoDB benar-benar "masih" belum memiliki operator yang sangat efisien untuk melakukan ini.

Anda dapat melakukan sesuatu seperti ini dengan MongoDB 3.2, tetapi ada "tangkapan" yang jelas:

db.Books.aggregate([
    { "$group": {
        "_id": "$company",
        "count": { "$sum": 1 },
        "urls": {
            "$push": "$url"
        }
    }},
    { "$sort": { "count": -1 } },
    { "$limit": 10 },
    { "$project": {
        "count": 1,
        "urls": { "$slice": ["$urls",0, 3] }
    }}
])

Dan masalah yang jelas adalah bahwa apa pun yang terjadi, Anda masih menambahkan semua dari konten "url" ke dalam larik yang dikelompokkan. Ini berpotensi melebihi batas BSON sebesar 16MB. Mungkin tidak, tetapi masih sedikit boros untuk menambahkan "semua" konten jika Anda hanya ingin "tiga".

Jadi meskipun demikian, mungkin lebih praktis untuk benar-benar menanyakan "url" secara terpisah pada masing-masing dari 10 hasil teratas.

Berikut daftar node.js yang menunjukkan:

var async = require('async'),
    mongodb = require('mongodb'),
    MongoClient = mongodb.MongoClient;

MongoClient.connect("mongodb://localhost/test",function(err,db) {

    if (err) throw err;

    // Get the top 10
    db.collection("Books").aggregate(
        [
            { "$group": {
                "_id": "$company",
                "count": { "$sum": 1 }
             }},
             { "$sort": { "count": -1 } },
             { "$limit": 10 }
        ],function(err,results) {
            if (err) throw err;

            // Query for each result and map query response as urls
            async.map(
                results,
                function(result,callback) {
                    db.collection("Books").find({ 
                       "company": result.company 
                    }).limit(3).toArray(function(err,items) {
                        result.urls = items.map(function(item) { 
                            return item.url;
                        });
                        callback(err,result);
                    })
                },
                function(err,results) {
                    if (err) throw err;
                    // each result entry has 3 urls
                }
            );
        }
     )

});

Ya itu lebih banyak panggilan ke database, tetapi sebenarnya hanya sepuluh dan karena itu tidak terlalu menjadi masalah.

nyata resolusi untuk ini tercakup dalam SERVER-9377 - Perpanjang $push atau $max untuk memungkinkan pengumpulan "top " N nilai per _id kunci dalam fase $grup . Ini memiliki status "Dalam Proses" yang menjanjikan, sehingga sedang dikerjakan secara aktif.

Setelah itu diselesaikan, maka satu pernyataan agregasi menjadi layak, sejak itu Anda akan dapat "membatasi" "url" yang dihasilkan di $push awal menjadi hanya tiga entri, daripada menghapus semua kecuali tiga setelah fakta.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. elemen pembaruan mongoid dalam array

  2. Apa perbedaan antara toGMTstring() dan toUTCstring()?

  3. MongoDB:Meminta beberapa koleksi dengan dua kueri?

  4. C# serialisasi kelas kompleks MongoDB

  5. Aliran Perubahan MongoDB:Bisakah saya mendapatkan nilai sebelum memperbarui/menghapus?