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

Aggregierte Mongo-Daten php

Die Datenstruktur hier ist keine gute Implementierung, es gibt viele Probleme, wie diese strukturiert ist, und sie ist für die Aggregation völlig ungeeignet. Die Hauptprobleme hier sind:

  • Ihre Struktur verwendet eigentlich keine Arrays, im Moment tut sie das nicht

  • Alle spezifischen Schlüsselnamen stellen ein echtes Problem dar, und dies kann vermieden werden.

Daher ist die einzige Möglichkeit, diese Art von Struktur zu durchlaufen, die Verwendung von JavaScript mit mapReduce.

Mapper definieren:

var mapper = function () {

  for ( var n in this.versions ) {
    for ( var k in this.versions[n].content ) {
      if (
        ( k != 'confirmed' ) ||
        ( k != 'visited' ) )
          emit(
            {
              type: this.chairtype,
              key: k
            },
            this.versions[n].content[k]
          );
    }
  }

};

Das geht also durch alle Einträge der Versionen und dann auch durch den Inhalt. Der Schlüssel wird für jeden der gewünschten Inhaltsschlüssel sowie durch den Schlüssel "Stuhltyp" ausgegeben. Und der Wert ist dieser übereinstimmende Wert.

Und dann ein Reducer:

var reducer = function (key,values) {

    return ( Array.sum( values ) != 0 ) 
        ? Array.sum( values ) / values.length : 0;

};

Das ist nur eine einfache Möglichkeit, einen Durchschnitt aus allen Werten zu erstellen, die für den Mapper mit demselben Schlüssel eingehen.

Während das also gut funktionieren sollte, sollten Sie Ihre Struktur ändern. Wenn Sie also tatsächlich so etwas hatten:

{
    "_id": ObjectId("52b85dfa32b6249513f15897"),
    "parent": "47de3176-bbc3-44e0-8063-8920ac56fdc8",
    "type": "chair",
    "chairtype": "E",
    "content": [
        { "key": "atkswlntfd", "value": 0, "version": 0 },
        { "key": "auwbsjqzir", "value": 0, "version": 0 },
        { "key": "avqrnjzbgd", "value": 0, "version": 0 }
    ]
}

Oder allgemein mehr oder weniger in dieser Form wird die Aggregationsoperation sehr einfach:

db.collection.aggregate([
    { "$unwind": "$content" },
    { "$group": {
       "_id": {
           "chairtype": "$chairtype",
           "key": "$content.key"
       },
       "average": { "$avg": "$content.value" }
    }}
])

Oder was auch immer für eine andere Variation davon erforderlich ist, aber jetzt wird es durch eine Änderung der Struktur ermöglicht.

Ohne dass das Dokument anders strukturiert ist, müssen Sie dazu mapReduce verwenden.