2016-09-26 56 views
0

我面临到MongoDB的查询转换到PHP如何在PHP中转换mongoDB查询?

一个问题这是我的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

我相信相同的查询可以通过聚合框架更高效地完成。聚合框架的性能要好得多,因为它在C++代码中“在”MongoDB内运行,因此比在捆绑的JS控制台内的V8/spidermonkey(取决于您的版本)内运行的mapReduce更高效。

考虑运行下面的管道,以获得期望的结果:

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); 

这教义蒙戈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)]); 

通过精简操作,可以运行命令:

$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"; 
} 
+0

类未发现异常MongoDate没有找到 –

+0

@chirdam我应该怎么做,以解决未发现异常类? –

+0

@IbrahimMAATKI您正在使用哪个PHP版本?根据这方面,这个问题的答案可能有所帮助http://stackoverflow.com/questions/34667609/ – chridam