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

Agregat Mongodb pada subdokumen dalam array

MapReduce lambat, tetapi dapat menangani kumpulan data yang sangat besar. Kerangka Agregasi di sisi lain sedikit lebih cepat, tetapi akan berjuang dengan volume data yang besar.

Masalah dengan struktur Anda yang ditampilkan adalah Anda perlu "$unwind" array untuk membuka data. Ini berarti membuat dokumen baru untuk setiap item array dan dengan kerangka kerja agregasi perlu melakukan ini di memori. Jadi, jika Anda memiliki 1000 dokumen dengan 100 elemen larik, Anda perlu membuat aliran 100.000 dokumen untuk mengelompokkannya dan menghitungnya.

Anda mungkin ingin mempertimbangkan untuk melihat apakah ada tata letak skema yang akan melayani kueri Anda dengan lebih baik, tetapi jika Anda ingin melakukannya dengan kerangka kerja Agregasi, inilah cara Anda dapat melakukannya (dengan beberapa data sampel sehingga seluruh skrip akan dimasukkan ke dalam shell);

db.so.remove();
db.so.ensureIndex({ "items.sku": 1}, {unique:false});
db.so.insert([
    {
        _id: 42,
        last_modified: ISODate("2012-03-09T20:55:36Z"),
        status: 'active',
        items: [
            { sku: '00e8da9b', qty: 1, item_details: {} },
            { sku: '0ab42f88', qty: 4, item_details: {} },
            { sku: '0ab42f88', qty: 4, item_details: {} },
            { sku: '0ab42f88', qty: 4, item_details: {} },
    ]
    },
    {
        _id: 43,
        last_modified: ISODate("2012-03-09T20:55:36Z"),
        status: 'active',
        items: [
            { sku: '00e8da9b', qty: 1, item_details: {} },
            { sku: '0ab42f88', qty: 4, item_details: {} },
        ]
    },
]);


db.so.runCommand("aggregate", {
    pipeline: [
        {   // optional filter to exclude inactive elements - can be removed    
            // you'll want an index on this if you use it too
            $match: { status: "active" }
        },
        // unwind creates a doc for every array element
        { $unwind: "$items" },
        {
            $group: {
                // group by unique SKU, but you only wanted to count a SKU once per doc id
                _id: { _id: "$_id", sku: "$items.sku" },
            }
        },
        {
            $group: {
                // group by unique SKU, and count them
                _id: { sku:"$_id.sku" },
                doc_count: { $sum: 1 },
            }
        }
    ]
    //,explain:true
})

Perhatikan bahwa saya telah $group'd dua kali, karena Anda mengatakan bahwa SKU hanya dapat dihitung satu kali per dokumen, jadi pertama-tama kita harus memilah pasangan doc/sku yang unik dan kemudian menghitungnya.

Jika Anda ingin hasilnya sedikit berbeda (dengan kata lain, PERSIS seperti pada sampel Anda) kami dapat $memproyeksikannya.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Perbedaan MongoDB antara kode kesalahan 11000 dan 11001

  2. Mengapa MongoDB memerlukan `unique:true` untuk membuat koleksi?

  3. Permintaan MongoDB lambat:dapatkah Anda menjelaskan alasannya?

  4. MongoEngine - Bidang yang dihapus masih memunculkan ValidationError

  5. Sebelum $unwind periksa apakah sub dokumen tidak kosong