(PECL mongo >=1.3.0)
MongoCollection::aggregate — aggregation フレームワークを使って集約する
$pipeline
[, array $op
[, array $...
]] )MongoDB の » aggregation フレームワーク を使うと、値を集約するときに MapReduce を使わずに済ませることができます。 MapReduce は強力な手段ですが、単にフィールドの合計や平均を調べたいだけといった単純な集約に使うには ちょっと大げさすぎることもあります。
このメソッドには、任意の数のパイプライン演算子を指定することもできるし、 パイプラインを構成する演算子の配列を一つだけ渡すこともできます。
pipeline
パイプライン演算子の配列、あるいは最初の演算子。
op
二番目のパイプライン演算子。
...
それ以降のパイプライン演算子。
集約の結果を配列で返します。成功した場合は ok が 1 になり、失敗した場合は 0 になります。
エラーが発生した場合は、次のキーを含む配列を返します。
例1 MongoCollection::aggregate() の例
次の例は、記事につけられたタグでグループ化した、作者名のセットを作ります。 aggregation フレームワークを呼ぶには、こんなコマンドを発行します。
<?php
$m = new Mongo;
$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() の例
人口が1000万人を上回るすべての州を返すには、こんな操作をします。
<?php
$m = new Mongo;
$c = $m->selectDB("test")->selectCollection("zips");
$out = $c->aggregate(array(
'$group' => array(
'_id' => '$state',
'totalPop' => array('$sum' => '$pop')
)
),
array(
'$match' => array('totalPop' => array('$gte' => 10*1000*1000))
)
);
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 Mongo;
$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)
}
[2]=>
array(2) {
["_id"]=>
string(2) "RI"
["avgCityPop"]=>
float(18933.283018868)
}
[3]=>
array(2) {
["_id"]=>
string(2) "AL"
["avgCityPop"]=>
float(7907.2152641879)
}
[4]=>
array(2) {
["_id"]=>
string(2) "NH"
["avgCityPop"]=>
float(5232.320754717)
}
...
[45]=>
array(2) {
["_id"]=>
string(2) "WY"
["avgCityPop"]=>
float(3359.9111111111)
}
[46]=>
array(2) {
["_id"]=>
string(2) "MN"
["avgCityPop"]=>
float(5335.4865853659)
}
[47]=>
array(2) {
["_id"]=>
string(2) "OK"
["avgCityPop"]=>
float(6155.7436399217)
}
[48]=>
array(2) {
["_id"]=>
string(2) "IL"
["avgCityPop"]=>
float(9931.0182450043)
}
[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)
}