MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Dati aggregati mongo php

La struttura dei dati qui non è una buona implementazione, ci sono molti problemi con il modo in cui è strutturata ed è completamente inadatta all'aggregazione. I problemi principali qui sono:

  • La tua struttura in realtà non utilizza alcun array, in questo momento non lo fa

  • Tutti i nomi di chiavi specifici rappresentano un vero problema e questo può essere evitato.

In quanto tale, l'unico modo per attraversare questo tipo di struttura è usare JavaScript con mapReduce.

Definizione di un mappatore:

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

};

Quindi ciò che sta facendo è scorrere ciascuna delle voci delle versioni e quindi anche tutto sul contenuto. La chiave viene emessa per ciascuna delle chiavi di contenuto desiderate, nonché dalla chiave "chairtype". E il valore è quel valore corrispondente.

E poi un riduttore:

var reducer = function (key,values) {

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

};

Che è solo un modo semplice per produrre una media da tutti i valori che arrivano per il mapper con la stessa chiave.

Quindi, mentre dovrebbe funzionare bene, quello che dovresti fare è cambiare la tua struttura. Quindi in effetti se avessi qualcosa del genere:

{
    "_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 }
    ]
}

O generalmente più o meno in quella forma, l'operazione di aggregazione diventa molto semplice:

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

O qualsiasi altra variazione di questo sia richiesta, ma ora è possibile modificando la struttura.

Quindi, senza che il documento sia strutturato in modo diverso, dovrai utilizzare mapReduce per farlo.