sql >> Databáze >  >> NoSQL >> MongoDB

Mongodb agreguje na vnořený dokument v poli

MapReduce je pomalý, ale dokáže zpracovat velmi velké soubory dat. Na druhou stranu agregační rámec je o něco rychlejší, ale bude bojovat s velkými objemy dat.

Problém s vaší ukázanou strukturou je v tom, že potřebujete "$unwind" pole, abyste otevřeli data. To znamená vytvoření nového dokumentu pro každou položku pole as agregačním rámcem, který to potřebuje, v paměti. Pokud tedy máte 1000 dokumentů se 100 prvky pole, bude potřeba vytvořit proud 100 000 dokumentů, aby je bylo možné seskupit podle a spočítat.

Možná budete chtít zvážit, zda existuje rozvržení schématu, které bude lépe serverovat vaše dotazy, ale pokud to chcete udělat s agregačním rámcem, můžete to udělat takto (s ukázkovými daty, aby se celý skript dostal do shellu);

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
})

Všimněte si, že jsem $group'd dvakrát, protože jste řekl, že SKU se může počítat pouze jednou na dokument, takže musíme nejprve roztřídit jedinečné páry doc/sku a poté je spočítat.

Pokud chcete výstup trochu jiný (jinými slovy, PŘESNĚ jako ve vašem vzorku), můžeme je $promítnout.



  1. Získání výjimky nulového ukazatele Mongo agregace pomocí jarních dat (dynamická pole)

  2. Snažím se spustit mongod server na ubuntu:výjimka v initAndListen:29 Datový adresář /data/db nenalezen., ukončení

  3. Redis with Resque a Rails:Příkaz ERR není povolen při použití paměti> 'maxmemory'

  4. Mongodb .net async čeká