【问题标题】:How to convert mongoDB Query in php?如何在 php 中转换 mongoDB 查询?
【发布时间】:2016-09-26 07:31:42
【问题描述】:

我在将 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();

【问题讨论】:

    标签: php mongodb mongodb-query


    【解决方案1】:

    我相信使用聚合框架可以更有效地完成相同的查询。聚合框架的性能要好得多,因为它在其 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);
    

    在学说 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";
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多