MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB 2.6 Aggregation Framework-Verbesserungen

Dies ist ein Gastbeitrag von Vlad Mihalcea. Vlad ist ein Softwarearchitekt mit einer Leidenschaft für Softwareintegration, hohe Skalierbarkeit und Parallelitätsherausforderungen. Hier ist ein Link zum ursprünglichen Beitrag.

MongoDB entwickelt sich schnell weiter. Die Version 2.2 führte das Aggregations-Framework als Alternative zum Abfragemodell Map-Reduce ein. Das Generieren aggregierter Berichte ist eine wiederkehrende Anforderung an Unternehmenssysteme, und MongoDB glänzt in dieser Hinsicht. Wenn Sie damit noch nicht vertraut sind, sollten Sie sich diese Einführung in das Aggregation Framework oder die Leitfäden zur Leistungsoptimierung und Datenmodellierung ansehen.

Lassen Sie uns das Datenmodell wiederverwenden, das ich zuerst eingeführt habe, während wir die blitzschnellen MongoDB-Einfügungsfunktionen demonstrieren:

{ "_id" :ObjectId("5298a5a03b3f4220588fe57c"), "created_on" :ISODate("2012-04-22T01:09:53Z"), "value" :0.1647851116706831}

MongoDB 2.6 Aggregationsverbesserungen

Wenn ich in der Version 2.4 die folgende Aggregationsabfrage ausführe:

db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC(2012, 0, 10)) } }},{ $group:{ _id :{ "minute" :{ $minute :"$created_on" } }, "values":{ $addToSet:"$value" } }}]); 

Ich habe die 16-MB-Grenze für das Aggregationsergebnis erreicht:

{ "errmsg" :"Ausnahme:Aggregationsergebnis überschreitet maximale Dokumentgröße (16 MB)", "code" :16389, "ok" :0}

MongoDB-Dokumente sind auf 16 MB begrenzt, und vor Version 2.6 war das Aggregationsergebnis ein BSON-Dokument. Die Version 2.6 ersetzte es stattdessen durch einen Cursor.

Das Ausführen derselben Abfrage auf 2.6 ergibt das folgende Ergebnis:

db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC(2012, 0, 10)) } }},{ $group:{ _id :{ "minute" :{ $minute :"$created_on" } }, "values":{ $addToSet:"$value" } }}]). objsLeftInBatch();14

Ich habe die Cursor-basierte objsLeftInBatch-Methode verwendet, um den Aggregationsergebnistyp zu testen, und die 16 MB-Beschränkung gilt nicht mehr für das Gesamtergebnis. Die inneren Ergebnisse des Cursors sind normale BSON-Dokumente, daher sind sie immer noch auf 16 MB begrenzt, aber das ist viel handlicher als das vorherige Gesamtergebnislimit.

Die Version 2.6 behebt auch die Einschränkungen des Aggregationsspeichers. Ein vollständiger Sammlungsscan wie:

db.randomData.aggregate( [{ $group:{ _id :{ "minute" :{ $minute :"$created_on" } }, "values":{ $addToSet:"$value" } }}]) .objsLeftInBatch();

kann mit folgendem Fehler enden:

{ "errmsg":"Ausnahme:Speicherlimit für $group überschritten, aber externes Sortieren nicht zugelassen. AllowDiskUse:true übergeben, um sich anzumelden.", "code" :16945, "ok" :0} 

Daher können wir jetzt große Sortiervorgänge mit dem Parameter allowDiskUse durchführen:

db.randomData.aggregate( [{ $group:{ _id :{ "minute" :{ $minute :"$created_on" } }, "values":{ $addToSet:"$value" } }}], { allowDiskUse :true}).objsLeftInBatch();

Die Version 2.6 ermöglicht es uns, das Aggregationsergebnis mithilfe der neu hinzugefügten Phase $out in einer anderen Sammlung zu speichern.

db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC(2012, 0, 10)) } }},{ $group:{ _id :{ "minute" :{ $minute :"$created_on" } }, "values":{ $addToSet:"$value" } }},{ $ out :"randomAggregates"}]);db.randomAggregates.count();60

Es wurden neue Operatoren wie let, map, cond hinzugefügt, um nur einige zu nennen.

Im nächsten Beispiel wird AM oder PM an die Zeitinformationen jedes spezifischen Ereigniseintrags angehängt.

var dataSet =db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC (2012, 0, 2)) } }},{ $project:{ "clock" :{ $let:{ vars:{ "hour":{ $substr:["$created_on", 11, -1] }, "am_pm":{ $cond:{ if:{ $lt:[ {$hour :"$created_on" }, 12 ] } , then:'AM',else:'PM'} } }, in:{ $concat :[ "$$hour", " ", "$$am_pm"] } } } }},{ $limit :10}]);dataSet.forEach(function(document) { printjson(document);});

Ergebnis:

"Uhr" :"16:07:14 Uhr""Uhr" :"22:14:42 Uhr""Uhr" :"21:46:12 Uhr""Uhr" :"03:35:00 Uhr „Uhr“ :„04:14:20 Uhr“ „Uhr“ :„03:41:39 Uhr“ „Uhr“ :„17:08:35 Uhr“ „Uhr“ :„18:44:02 Uhr“ Uhr" :"19:36:07 Uhr""Uhr" :"07:37:55 Uhr"

Schlussfolgerung

MongoDB 2.6-Version enthält viele andere Verbesserungen wie Massenoperationen oder Indexüberschneidungen. MongoDB entwickelt sich ständig weiter und bietet eine praktikable Alternative für die dokumentenbasierte Speicherung. Bei einer solchen Entwicklungsrate ist es kein Wunder, dass sie 2013 zur Datenbank des Jahres gekürt wurde.