MongoCollection::group

(PECL mongo >=0.9.2)

MongoCollection::groupLleva a cabo una operación similar al comando GROUP BY de SQL

Descripción

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

Parámetros

keys

Campos a agrupar. Si se pasa un array o un objeto que no es de código, será la clave usada para agrupar resultados.

1.0.4+: Si keys es una instancia de MongoCode, keys será tratado como una función que devuelve la clave con la que agrupar (revise el ejemplo de abajo sobre "Pasando una función a keys").

initial

Valor inicial del objeto contador combinado.

reduce

Una función que toma dos argumentos (el documento actual y la agregación en este punto) y realiza la agregación.

options

Parámetros opcionales para el comando group. Las opciones válidas incluyen:

  • "condition"

    Condición para incluir un documento a la agregación.

  • "finalize"

    Función que se invoca por cada clave única que toma la salida de la función reduce.

Valores devueltos

Devuelve un array que contiene el resultado.

Historial de cambios

Versión Descripción
1.2.11 Emite un error de nivel E_DEPRECATED cuando options es de tipo scalar.

Ejemplos

Ejemplo #1 Ejemplo de MongoCollection::group()

Agrupa los documentos por categoría y crea una lista de los nombres que hay dentro de la categoría.

<?php

$collection
->insert(array("categoria" => "fruta""nombre" => "manzana"));
$collection->insert(array("categoria" => "fruta""nombre" => "melocoton"));
$collection->insert(array("categoria" => "fruta""nombre" => "platano"));
$collection->insert(array("categoria" => "verdura""nombre" => "maiz"));
$collection->insert(array("categoria" => "verdura""nombre" => "brocoli"));

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

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

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

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

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

?>

El resultado del ejemplo sería algo similar a:

[{"categoria":"fruta","items":["manzana","melocoton","platano"]},{"categoria":"verdura","items":["maiz","brocoli"]}]

Ejemplo #2 Ejemplo de MongoCollection::group()

Este ejemplo no utiliza ninguna clave, por lo que cada documento será su propio grupo. Además, usa una condición: sólo los documentos que la cumplan, serán procesados por la función de agrupación.

<?php

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

// usar todos los campos
$claves = array();

// establecer valores iniciales
$inicial = array("count" => 0);

// función JavaScript a realizar
$reduce "function (obj, prev) { prev.count++; }";

// usar sólo los documentos donde el campo "a" es mayor que 1
$condicion = array('condition' => array("a" => array( '$gt' => 1)));

$g $collection->group($claves$inicial$reduce$condicion);

var_dump($g);

?>

El resultado del ejemplo sería algo similar a:

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

Ejemplo #3 Pasando una función a keys

Si se desea agrupar por algo distinto a un nombre de campo, se puede pasar una función como primer parámetro de MongoCollection::group() y se ejecutará con cada documento. Se usará el valor devuelto de la función como valor de agrupación.

Este ejemplo demuestra cómo agrupar por el campo num módulo 4 (num % 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 3 notes

up
1
ronan dot guilloux at gmail dot com
1 year 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
-1
nick at pitchinteractive dot com
2 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
-1
Evgeniy Abduzhapparov
3 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