2013-01-02 8 views
1

J'ai des documents au format suivantMongoDB agrégation PHP, groupe par Heures

{ 
    "_id" : ObjectId("12e123123123123123"), 
    "client_id" : "12345667889", 
    "resource" : "test/test", 
    "version" : "v2", 
    "ts" : new Date("Wed, 02 Jan 2013 15:34:58 GMT +08:00") 
} 

Le ts est un champ MongoDate().

Je suis en train d'utiliser une fonction d'agrégation MongoDB en php groupe par client_id et l'heure et compter l'utilisation pour afficher dans un tableau/graphique

Ceci est ma tentative actuelle

$usage = $this->db->Usage->aggregate(array(array(
    '$project' => array(
    'hour' => array(
     'years' => array('$year' => '$ts'), 
     'months' => array('$month' => '$ts'), 
     'days' => array('$dayOfMonth' => '$ts'), 
     'hours' => array('$hour' => '$ts'), 
    ) 
), 
    '$group' => array(
    '_id' => array(
     'client_id' => '$client_id', 
     'hour' => '$hour', 
    ), 
    'number' => array('$sum' => 1), 
) 
))); 

Malheureusement, ma réponse I Je reviens juste en regroupant par le client_id et rien d'autre.

[result] => Array 
    (
     [0] => Array 
      (
       [_id] => Array 
        (
         [client_id] => adacf8deba7066e4 
        ) 

       [number] => 12 
      ) 

    ) 

Toute personne en mesure de me diriger dans la bonne direction, ou avez-vous une autre solution à grouper par heure? PHP requiert que vous placiez chaque pipeline dans un tableau séparé et que vous placiez le tout dans un tableau. voir la solution de mise à jour ci-dessous avec l'aide de JohnnyHK

$usage = $this->db->Usage->aggregate(array(array(
     '$project' => array(
      'client_id' => 1, 
      'hour' => array(
       'years' => array('$year' => '$ts'), 
       'months' => array('$month' => '$ts'), 
       'days' => array('$dayOfMonth' => '$ts'), 
       'hours' => array('$hour' => '$ts'), 
      ) 
     )),array(
     '$group' => array(
      '_id' => array(
       'client_id' => '$client_id', 
       'hour' => '$hour', 
      ), 
      'number' => array('$sum' => 1), 
     ) 
    ))); 

Répondre

4

Il ne devrait pas créer les résultats que vous voyez, mais vous devez inclure dans votre client_id opérateur $project afin qu'il soit à la disposition de l'opérateur $group.

'$project' => array(
    'client_id' => 1, 
    'hour' => array(
    'years' => array('$year' => '$ts'), 
    'months' => array('$month' => '$ts'), 
    'days' => array('$dayOfMonth' => '$ts'), 
    'hours' => array('$hour' => '$ts'), 
) 
), 

L'équivalent shell a travaillé après avoir fait ce changement:

db.test.aggregate(
    { $project: { 
     hour: { 
      years: {$year: '$ts'}, 
      months: {$month: '$ts'}, 
      days: {$dayOfMonth: '$ts'}, 
      hours: {$hour: '$ts'} 
     }, 
     client_id: '$client_id' 
    }}, 
    { $group: { 
     _id: { client_id: '$client_id', hour: '$hour' }, 
     number: { $sum: 1} 
    }}) 

retourné:

{ 
    "result": [ 
    { 
     "_id": { 
     "client_id": "12345667889", 
     "hour": { 
      "years": 2013, 
      "months": 1, 
      "days": 2, 
      "hours": 7 
     } 
     }, 
     "number": 1 
    } 
    ], 
    "ok": 1 
} 
+0

Je reçois la même réponse. J'ai essayé la même chose dans le shell et je récupère le même mauvais résultat, ce qui me fait penser que cela a quelque chose à voir avec la configuration de ma collection ou avec Mongodb lui-même. Je cours la version 2.2.2. – Balthasar

+0

Étrange. J'ai ajouté l'équivalent shell que j'utilisais pour tester ceci avec MongoDB v2.2.2. – JohnnyHK

+0

Génial l'a réparé. C'était la façon dont php requis pour passer à travers les variables. L'ajout du client_id était nécessaire dans le projet. Je vais mettre à jour ma question avec la solution. – Balthasar