我遇到了将mongoDB查询转换为php
的问题这是我的mongoDB查询
db.contact_facts.mapReduce(
function() {
var k = new Date(this.date);
k.setHours(0);
k.setMinutes(0);
k.setSeconds(0);
k.setMilliseconds(0);
emit({idM:this.idMailing,
fact:this.fact,
year:k.getFullYear(),
month:k.getMonth(),
day:k.getDate()
}, 1);
},
function (key, values) {
return Array.sum(values);
},
{
query: { date: { $gt: ISODate('2016-09-20') } },
out: { reduce: "contact_fact_stats2"},
}
);
我遇到了将此行转换为php代码的问题
query: { date: { $gt: ISODate('2016-09-20') } },
这是在php中写的
$dm = $this->getContainer()->get('doctrine_mongodb')->getManager();
$qb = $dm->createQueryBuilder('AtayenMainBundle:ContactFact');
$qb->field('date')->equals("ISODate('2016-09-20T08:42:30.000Z')");
$qb->map('function() {
var k = new Date(this.date);
k.setHours(0);
k.setMinutes(0);
k.setSeconds(0);
k.setMilliseconds(0);
emit({idM:this.idMailing,fact:this.fact,date:this.date}, 1)}');
$qb->reduce('function(key, values) {
return Array.sum(values);
}');
$cursor = $qb->getQuery()->execute();
答案 0 :(得分:0)
我相信使用聚合框架可以更有效地完成相同的查询。聚合框架的性能更好,因为它运行"内部" MongoDB在其C ++代码中比mapReduce更有效,mapReduce在捆绑的JS控制台中的V8 / spidermonkey(取决于您的版本)环境中运行。
考虑运行以下管道以获得所需的结果:
var pipeline = [
{ "$match": { "date": { "$gt": new Date("2016-09-20") } } },
{
"$project": {
"fact": 1,
"idMailing": 1,
"formattedDate": {
"$dateToString": { "format": "%Y-%m-%d", "date": "$date" }
}
}
},
{
"$group": {
"_id": {
"fact": "$fact",
"idM": "$idMailing",
"formattedDate": "$formattedDate"
},
"count": { "$sum": 1 }
}
}
]
db.contact_facts.aggregate(pipeline);
在doctrine mongo odm中你可以使用命令函数运行你的管道操作,如下所示:
$connection = $this->getContainer()->get('doctrine_mongodb')->getConnection();
$mongo = $connection->getMongo();
if (!$mongo) {
$connection->connect();
$mongo = $connection->getMongo();
}
$db = $mongo->selectDB('test_database');
// construct pipeline
$pipeline = array(
array("$match" => array("date" => array("$gt" => new MongoDate(strtotime("2016-09-20")) ) ) ),
array(
"$project" => array(
"formattedDate" => array(
"$dateToString" => array("format" => "%Y-%m-%d", "date"=> "$date")
),
"fact" => 1,
"idMailing" => 1
)
),
array(
"$group" => array(
"_id" => array(
"fact" => "$fact",
"idM" => "$idMailing",
"formattedDate" => "$formattedDate"
),
"count" => array( "$sum" => 1 )
)
)
);
// run the aggregate command
$aggregate_results = $db ->command(array(
"aggregate" => "contact_facts",
"pipeline" => $pipeline
));
或创建聚合查询:
$expr = new \Solution\MongoAggregation\Pipeline\Operators\Expr;
$aq = $this->get('doctrine_mongodb.odm.default_aggregation_query')
->getCollection('AtayenMainBundle:ContactFact')->createAggregateQuery()
->group(['_id' => [
'year' => $expr->year('$date'),
'month' => $expr->month('$date'),
'day' => $expr->day('$date'),
'fact' => '$fact',
'idMailing' => '$idMailing'
], 'count' => $expr->sum(1)]);
使用mapReduce操作,您可以将命令运行为:
$connection = $this->getContainer()->get('doctrine_mongodb')->getConnection();
$mongo = $connection->getMongo();
if (!$mongo) {
$connection->connect();
$mongo = $connection->getMongo();
}
$db = $mongo->selectDB('test_database');
// construct map and reduce functions
$map = new MongoCode("function() {
var k = new Date(this.date);
k.setHours(0);
k.setMinutes(0);
k.setSeconds(0);
k.setMilliseconds(0);
var obj = {
idM: this.idMailing,
fact: this.fact,
year: k.getFullYear(),
month: k.getMonth(),
day: k.getDate()
};
emit(obj, 1);
}");
$reduce = new MongoCode("function (key, values) {
return Array.sum(values);
}");
$mr = $db->command(array(
"mapreduce" => "contact_facts",
"map" => $map,
"reduce" => $reduce,
"query" => array("date" => array("$gt" => new MongoDate(strtotime("2016-09-20")) ) ),
"out" => array("merge" => "eventCounts")));
$results = $db->selectCollection($mr['result'])->find();
foreach ($results as $res) {
echo "{$res['_id']} had {$res['value']} counts.\n";
}