MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Agréger les données mongo php

La structure de données ici n'est pas une bonne implémentation, il y a beaucoup de problèmes avec la façon dont cela est structuré et elle est complètement inadaptée à l'agrégation. Les principaux problèmes ici sont :

  • Votre structure n'utilise en fait aucun tableau, ce n'est pas le cas pour le moment

  • Tous les noms de clés spécifiques posent un vrai problème, et cela peut être évité.

En tant que tel, le seul moyen de traverser ce type de structure consiste à utiliser JavaScript avec mapReduce.

Définition d'un mappeur :

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

};

Donc, ce que cela fait, c'est parcourir chacune des entrées de versions, puis également tout ce qui concerne le contenu. La clé est émise pour chacune des clés de contenu que vous souhaitez ainsi que par la clé "chairtype". Et la valeur est cette valeur correspondante.

Et puis un réducteur :

var reducer = function (key,values) {

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

};

Ce qui est juste un moyen simple de produire une moyenne à partir de toutes les valeurs entrant pour le mappeur avec la même clé.

Donc, même si cela devrait bien fonctionner, ce que vous devriez faire, c'est changer votre structure. Donc, en fait, si vous aviez quelque chose comme ça :

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

Ou généralement plus ou moins sous cette forme, l'opération d'agrégation devient très simple :

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

Ou toute autre variante requise, mais maintenant cela est rendu possible en modifiant la structure.

Ainsi, sans que le document soit structuré différemment, vous devrez utiliser mapReduce pour ce faire.