MapReduce ist langsam, kann aber sehr große Datenmengen verarbeiten. Das Aggregation-Framework hingegen ist etwas schneller, wird aber mit großen Datenmengen zu kämpfen haben.
Das Problem mit Ihrer gezeigten Struktur ist, dass Sie die Arrays "$unwind" müssen, um die Daten zu knacken. Dies bedeutet, dass für jedes Array-Element ein neues Dokument erstellt wird, und mit dem Aggregations-Framework muss dies im Speicher erfolgen. Wenn Sie also 1000 Dokumente mit 100 Array-Elementen haben, müssen Sie einen Stream von 100.000 Dokumenten erstellen, um sie zu gruppieren und zu zählen.
Vielleicht möchten Sie prüfen, ob es ein Schema-Layout gibt, das Ihre Abfragen besser verarbeitet, aber wenn Sie es mit dem Aggregation-Framework machen möchten, können Sie es hier tun (mit einigen Beispieldaten, damit das gesamte Skript in die Shell fällt).;
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
})
Beachten Sie, dass ich zweimal $group'd gemacht habe, weil Sie sagten, dass eine SKU nur einmal pro Dokument zählen kann, also müssen wir zuerst die eindeutigen Dokument/Sku-Paare aussortieren und sie dann hochzählen.
Wenn Sie eine etwas andere Ausgabe wünschen (mit anderen Worten, GENAU wie in Ihrem Beispiel), können wir sie $projizieren.