PHP Velho Oeste 2024

MongoCollection::group

(PECL mongo >=0.9.2)

MongoCollection::groupEffecture une opération de regroupement

Description

public MongoCollection::group ( mixed $keys , array $initial , MongoCode $reduce [, array $options = array() ] ) : array

Liste de paramètres

keys

Les champs avec lesquels faire le regroupement. Si un tableau ou un objet non-code est passé, ce sera la clé utilisée pour grouper les résultats.

1.0.4+: Si keys est une instance de MongoCode, keys sera considéré comme une fonction qui retourne la clé pour effectuer le regroupement (voir l'exemple ci-dessous sur le passage d'une fonction keys).

initial

Valeur initiales des compteurs d'agrégation.

reduce

Fonction acceptant deux arguments (le document courant et l'agrégation à ce point) et effectue l'agrégation.

options

Paramètres optionnels pour la commande de groupe. Les options accéptées sont:

  • "condition"

    Critère pour inclure un document dans l'agrégation.

  • "finalize"

    Fonction appelée une fois par clé unique qui prend le rendu final de la fonction de réduction.

  • "maxTimeMS"

    Spécifie une limite cumulative de temps, en millisecondes, pour procéder à l'opération (n'inclut pas le temps d'inactivité). Si l'opération n'est pas terminée durant cette période, une exception MongoExecutionTimeoutException sera émise.

Valeurs de retour

Retourne un tableau contenant les résultats.

Historique

Version Description
1.5.0 Ajout de l'option "maxTimeMS".
1.2.11 Lance une alerte de niveau E_DEPRECATED lorsque le paramètre options est de type scalar.

Exemples

Exemple #1 Exemple avec MongoCollection::group()

Cet exemple regroupe des documents par catégorie et crée une liste de noms à l'intérieur des catégories

<?php

$collection
->insert(array("category" => "fruit""name" => "apple"));
$collection->insert(array("category" => "fruit""name" => "peach"));
$collection->insert(array("category" => "fruit""name" => "banana"));
$collection->insert(array("category" => "veggie""name" => "corn"));
$collection->insert(array("category" => "veggie""name" => "broccoli"));

$keys = array("category" => 1);

$initial = array("items" => array());

$reduce "function (obj, prev) { prev.items.push(obj.name); }";

$g $collection->group($keys$initial$reduce);

echo 
json_encode($g['retval']);

?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

[{"category":"fruit","items":["apple","peach","banana"]},{"category":"veggie","items":["corn","broccoli"]}]

Exemple #2 Exemple avec MongoCollection::group()

Cet exemple n'utilise aucune clé, donc chaque document sera dans son propre groupe. Il y a aussi une condition: seuls les documents qui correspondent à cette condition seront traités par la fonction de regroupement.

$collection->save(array("a" => 2));
$collection->save(array("b" => 5));
$collection->save(array("a" => 1));

// Utilisation de tous les champs
$keys = array();

// Défini les valeurs initiales
$initial = array("count" => 0);

// Fonction JavaScript pour traitement
$reduce = "function (obj, prev) { prev.count++; }";

// N'utilisez que les documents où le champ "a" est plus grand que 1
$condition = array('condition' => array("a" => array( '$gt' => 1)));

$g = $collection->group($keys, $initial, $reduce, $condition);

var_dump($g);

?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

array(4) {
  ["retval"]=>
  array(1) {
    [0]=>
    array(1) {
      ["count"]=>
      float(1)
    }
  }
  ["count"]=>
  float(1)
  ["keys"]=>
  int(1)
  ["ok"]=>
  float(1)
}

Exemple #3 Passer une fonction keys

Si vous voulez grouper par quelque chose d'autre qu'un nom de champ, vous pouvez passer une fonction comme premier paramètre à la méthode MongoCollection::group() et elle sera exécutée sur chacun des documents. La valeur retournée de cette fonction sera utilisée comme valeur de regroupement.

Cet exemple montre comment regrouper par le numéro du champ, modulo 4.

<?php

$c
->group(new MongoCode('function(doc) { return {mod : doc.num % 4}; }'),
     array(
"count" => 0),
     new 
MongoCode('function(current, total) { total.count++; }'));

?>
add a note add a note

User Contributed Notes 4 notes

up
2
nick at pitchinteractive dot com
12 years ago
Here's my code to do an equivalent of a GROUP BY and a SUM

<?php
$contributionCol
= $db->customers->contribution;
$group = $contributionCol->group(array('date' => true), array('sum' => 0), "function (obj, prev) { prev['sum'] += obj.amount; }");
?>

This groups by the 'date' column and sums over the 'amount' column. In my testing this was much slower than querying all rows and doing the Group by code with PHP. It could just be my particular setup and data set.

Also at first my amount column was a string, which caused the results to be concatenated rather than arithmetic addition, something else to watch out for.

[red.: Instead of this, please use the new aggregation framework. See the documentation for MongoCollection::aggregate]
up
0
ury dot zend at gmail dot com
9 years ago
quoting Evgeniy Abduzhapparov example for correction, since is not working on newest php mongo driver version

instead of use:
<?php
$initial
= array('tags'=>array(), 'count'=>0);
?>
for var tags,
you have to cast the empty array to an object or use new stdClass()
<?php
$initial
= array('tags'=> (object) array(), 'count'=>0);

$initial = array('tags'=> new stdClass(), 'count'=>0);
?>
up
-1
ronan dot guilloux at gmail dot com
11 years ago
Since the $options argument is no longer a scalar (deprecated since the 1.2.11 version of the Mongo's PHP driver), you now must compose your $options as an associative array, otherwise you'll rise a "Implicitly passing condition as $options will be removed in the future" alert.

Example:

<?php

$m
= new Mongo();
$db = $m->selectDB('test');
$collection = new MongoCollection($db, 'FooBar');

// grouping results by categories, where foo is 'bar'
$keys = array('categorie'=>true, 'foo'=>true); // the fields list we want to return
$initial = array('count' => 0); // gets a subtotal for each categorie
$reduce = "function(obj,prev) { prev.count += 1; }"; // yes, this is js code
$conditions = array('foo'=> 'bar');
$grouped = $myColl::group($keys, $initial, $reduce, array('condition'=>$conditions));
$result = $grouped['retval'];

?>
up
-3
Evgeniy Abduzhapparov
13 years ago
Here I am posting how I get tags from my documents. Documents should have 'tags' field which is array of strings:
{'tags':['php', 'mongo']}
<?php
$keys
= array();
$initial = array('tags'=>array(), 'count'=>0);
$reduce = 'function (doc, total) { if (doc.tags.length) {doc.tags.forEach(function (e) {total.tags[e]=total.tags[e]||0; total.tags[e]++; total.count++;});} }';
$criteria = array(
   
'condition' => array(
       
'tags' => array('$exists'=>true)
    ),
);
?>
To Top