MongoCollection::aggregate

(PECL mongo >=1.3.0)

MongoCollection::aggregateВыполняет агрегацию с использованием структуры агрегации

Описание

public MongoCollection::aggregate ( array $pipeline , array $options = ? ) : array
public MongoCollection::aggregate ( array $op , array ...$ops ) : array

» Платформа агрегации MongoDB предоставляет средства для вычисления агрегированных значений без использования MapReduce. Несмотря на то, что MapReduce является мощным средством, оно зачастую сложнее, чем необходимо для многих простых задач агрегирования, таких как суммирование или вычисление среднего значения полей.

Метод принимает либо переменное количество операторов конвейера, либо один массив операторов, составляющих конвейер.

Список параметров

pipeline

Массив операторов конвейера.

options

Опции для команды агрегации. Допустимые варианты:

  • "allowDiskUse"

    Разрешить этапы агрегации для записи во временные файлы

  • "cursor"

    Опции, управляющие созданием объекта курсора. Эта опция заставляет команду возвращать результат документа, подходящий для создания MongoCommandCursor. Если вам нужно использовать эту опцию, вы должны рассмотреть возможность использования MongoCollection::aggregateCursor().

  • "explain"

    Вернуть информацию об обработке конвейера.

  • "maxTimeMS"

    Указывает суммарный лимит времени в миллисекундах на обработку операции (не включая время простоя) на сервере. Если операция на стороне сервера не завершилась за это время, то вызывается исключение MongoExecutionTimeoutException.

Or

op

Первый оператор конвейера.

ops

Дополнительные операторы конвейера.

Возвращаемые значения

Результат агрегации в виде массива. ok будет установлен в качестве 1 в случае успеха, 0 в случае ошибки.

Ошибки

При возникновении ошибки возвращается массив со следующими ключами:

  • errmsg - с указанием причины отказа
  • code - код ошибки сбоя
  • ok - будет установлен 0.

Список изменений

Версия Описание
PECL mongo 1.5.0 Добавлен необязательный аргумент options

Примеры

Пример #1 Пример использования MongoCollection::aggregate()

В следующем примере операция агрегирования поворачивает данные, чтобы создать набор имён авторов, сгруппированных по тегам, применённым к статье. Вызовите структуру агрегации, введя следующую команду:

<?php
$m 
= new MongoClient("localhost");
$c $m->selectDB("examples")->selectCollection("article");
$data = array (
    
'title' => 'this is my title',
    
'author' => 'bob',
    
'posted' => new MongoDate,
    
'pageViews' => 5,
    
'tags' => array ( 'fun''good''fun' ),
    
'comments' => array (
      array (
        
'author' => 'joe',
        
'text' => 'this is cool',
      ),
      array (
        
'author' => 'sam',
        
'text' => 'this is bad',
      ),
    ),
    
'other' =>array (
      
'foo' => 5,
    ),
);
$d $c->insert($data, array("w" => 1));

$ops = array(
    array(
        
'$project' => array(
            
"author" => 1,
            
"tags"   => 1,
        )
    ),
    array(
'$unwind' => '$tags'),
    array(
        
'$group' => array(
            
"_id" => array("tags" => '$tags'),
            
"authors" => array('$addToSet' => '$author'),
        ),
    ),
);
$results $c->aggregate($ops);
var_dump($results);
?>

Результат выполнения данного примера:

array(2) {
  ["result"]=>
  array(2) {
    [0]=>
    array(2) {
      ["_id"]=>
      array(1) {
        ["tags"]=>
        string(4) "good"
      }
      ["authors"]=>
      array(1) {
        [0]=>
        string(3) "bob"
      }
    }
    [1]=>
    array(2) {
      ["_id"]=>
      array(1) {
        ["tags"]=>
        string(3) "fun"
      }
      ["authors"]=>
      array(1) {
        [0]=>
        string(3) "bob"
      }
    }
  }
  ["ok"]=>
  float(1)
}

В следующих примерах используется » набор данных zipcode. Используйте mongoimport для загрузки этого набора данных в ваш экземпляр mongod.

Пример #2 Пример использования MongoCollection::aggregate()

Чтобы вернуть все штаты с населением более 10 миллионов, используйте следующую операцию агрегирования:

<?php
$m 
= new MongoClient("localhost");
$c $m->selectDB("test")->selectCollection("zips");

$pipeline = array(
    array(
        
'$group' => array(
            
'_id' => array('state' => '$state'),
            
'totalPop' => array('$sum' => '$pop')
        )
    ),
    array(
        
'$match' => array(
            
'totalPop' => array('$gte' => 10 1000 1000)
        )
    ),
);
$out $c->aggregate($pipeline);
var_dump($out);
?>

Результатом выполнения данного примера будет что-то подобное:

array(2) {
  ["result"]=>
  array(7) {
    [0]=>
    array(2) {
      ["_id"]=>
      string(2) "TX"
      ["totalPop"]=>
      int(16986510)
    }
    [1]=>
    array(2) {
      ["_id"]=>
      string(2) "PA"
      ["totalPop"]=>
      int(11881643)
    }
    [2]=>
    array(2) {
      ["_id"]=>
      string(2) "NY"
      ["totalPop"]=>
      int(17990455)
    }
    [3]=>
    array(2) {
      ["_id"]=>
      string(2) "IL"
      ["totalPop"]=>
      int(11430602)
    }
    [4]=>
    array(2) {
      ["_id"]=>
      string(2) "CA"
      ["totalPop"]=>
      int(29760021)
    }
    [5]=>
    array(2) {
      ["_id"]=>
      string(2) "OH"
      ["totalPop"]=>
      int(10847115)
    }
    [6]=>
    array(2) {
      ["_id"]=>
      string(2) "FL"
      ["totalPop"]=>
      int(12937926)
    }
  }
  ["ok"]=>
  float(1)
}

Пример #3 Пример использования MongoCollection::aggregate()

Чтобы получить среднюю численность населения по городам в каждом штате, используйте следующую операцию агрегирования:

<?php
$m 
= new MongoClient;
$c $m->selectDB("test")->selectCollection("zips");

$out $c->aggregate(
    array(
        
'$group' => array(
            
'_id' => array('state' => '$state''city' => '$city' ),
            
'pop' => array('$sum' => '$pop' )
        )
    ),
    array(
        
'$group' => array(
            
'_id' => '$_id.state',
            
'avgCityPop' => array('$avg' => '$pop')
        )
    )
);

var_dump($out);
?>

Результатом выполнения данного примера будет что-то подобное:

array(2) {
  ["result"]=>
  array(51) {
    [0]=>
    array(2) {
      ["_id"]=>
      string(2) "DC"
      ["avgCityPop"]=>
      float(303450)
    }
    [1]=>
    array(2) {
      ["_id"]=>
      string(2) "DE"
      ["avgCityPop"]=>
      float(14481.913043478)
    }
...
    [49]=>
    array(2) {
      ["_id"]=>
      string(2) "WI"
      ["avgCityPop"]=>
      float(7323.0074850299)
    }
    [50]=>
    array(2) {
      ["_id"]=>
      string(2) "WV"
      ["avgCityPop"]=>
      float(2759.1953846154)
    }
  }
  ["ok"]=>
  float(1)
}

Пример #4 MongoCollection::aggregate()с параметрами команды

Чтобы вернуть информацию о том, как будет обрабатываться конвейер, мы используем опцию команды explain:

<?php
$m 
= new MongoClient;
$c $m->selectDB("test")->selectCollection("zips");

$pipeline = array(
    array(
        
'$group' => array(
            
'_id' => '$state',
           
'totalPop' => array('$sum' => '$pop'),
        ),
    ),
    array(
        
'$match' => array(
            
'totalPop' => array('$gte' => 10 1000 1000)
        )
    ),
    array(
        
'$sort' => array("totalPop" => -1),
    ),
);

$options = array("explain" => true);
$out $c->aggregate($pipeline$options);
var_dump($out);
?>

Результатом выполнения данного примера будет что-то подобное:

array(2) {
  ["stages"]=>
  array(4) {
    [0]=>
    array(1) {
      ["$cursor"]=>
      array(3) {
        ["query"]=>
        array(0) {
        }
        ["fields"]=>
        array(3) {
          ["pop"]=>
          int(1)
          ["state"]=>
          int(1)
          ["_id"]=>
          int(0)
        }
        ["plan"]=>
        array(4) {
          ["cursor"]=>
          string(11) "BasicCursor"
          ["isMultiKey"]=>
          bool(false)
          ["scanAndOrder"]=>
          bool(false)
          ["allPlans"]=>
          array(1) {
            [0]=>
            array(3) {
              ["cursor"]=>
              string(11) "BasicCursor"
              ["isMultiKey"]=>
              bool(false)
              ["scanAndOrder"]=>
              bool(false)
            }
          }
        }
      }
    }
    [1]=>
    array(1) {
      ["$group"]=>
      array(2) {
        ["_id"]=>
        string(6) "$state"
        ["totalPop"]=>
        array(1) {
          ["$sum"]=>
          string(4) "$pop"
        }
      }
    }
    [2]=>
    array(1) {
      ["$match"]=>
      array(1) {
        ["totalPop"]=>
        array(1) {
          ["$gte"]=>
          int(10000000)
        }
      }
    }
    [3]=>
    array(1) {
      ["$sort"]=>
      array(1) {
        ["sortKey"]=>
        array(1) {
          ["totalPop"]=>
          int(-1)
        }
      }
    }
  }
  ["ok"]=>
  float(1)
}

Смотрите также

add a note add a note

User Contributed Notes 1 note

up
1
mike at eastghost dot com
4 years ago
COPY ONE COLLECTION TO ANOTHER COLLECTION IN SAME DATABASE

db.myoriginal.aggregate( [ [ $match: [] ], [ $out: "mycopy" ] ] )

a LOT faster than doing many inserts in a forEach loop.
< 2 seconds to copy 50,000 documents each a few KB.
12GB of data in 1-2 minutes on a i5 PC.
Best part : it's non-blocking!
Target can't be a capped collection.

ymmv
To Top