简体   繁体   English

MongoDB聚合在PHP中不起作用(或非常慢),并且在Shell中完美地工作?

[英]MongoDB aggregation does not work (or is very slow) with PHP and works perfectly in shell?

I'm trying to use the aggregate method on my collection (containing more than 20M documents). 我正在尝试在集合中使用聚合方法(包含超过2000万个文档)。

I first tried it in the Windows shell : 我首先在Windows shell中尝试过:

db.data.aggregate([
{$match: {firstname: "Roger"}},
{$group:{"_id":"$id_car",count:{$sum: 1}}},
{$sort: {count: -1}},
{$limit: 50}])

And it works perfectly, returning the results after a few seconds. 它运行完美,几秒钟后返回结果。

When I "translate" it in PHP : 当我在PHP中“翻译”它时:

$data = $db->data;
$ops = array(
    array(
         '$match' => array(
             'firstname' => 'Roger'
         )
    ),
    array(
        '$group' => array(
            '_id' => '$id_car',
            'count' => array(
                '$sum' => 1     
            )       
        )
    ),
    array(
        '$sort' => array(
            'count' => -1
        )
    ),
    array(
        '$limit' => 4       
    )
);
$res = $data->aggregate($ops);

I get a timeout PHP Fatal error : 我收到超时PHP致命错误:

Uncaught exception 'MongoCursorTimeoutException' with message 'localhost:27017: cursor timed out (timeout: 30000, time left: 30:0, status: 0)'

I don't know if I've made a mistake in my PHP code, or if aggregate is supposed to be much slower in PHP than in shell ? 我不知道我是否在我的PHP代码中犯了一个错误,或者是否应该认为聚合在PHP中比在shell中要慢得多?

Also, I have added an index on "firstname" field to make the query go faster. 另外,我在“名字”字段上添加了索引,以使查询更快。

By the way, is there any way to set the timeout to infinity for this kind of call ? 顺便说一句,有没有办法将这种呼叫的超时设置为无穷大?

Thanks a lot for your help ! 非常感谢你的帮助 !

Joe

I don't really know about your issue (PHP being slower than the MongoShell), but something I've done that allowed me to run an aggregation in PHP (due to the timeout problems) is changing the way I invoked the aggregation. 我真的不知道您的问题(PHP比MongoShell慢),但是我做的一些事情(由于超时问题)使我可以在PHP中运行聚合,这正在改变我调用聚合的方式。

Hope this helps someone that reaches this page because of the timeout problems, like I did! 希望这可以帮助由于超时问题而到达此页面的人,就像我一样!

Instead of $data->aggregate($ops) I ran the following equivalent to your case: 我运行了与您的情况相同的命令,而不是$data->aggregate($ops)

$db->command(
    array('aggregate' => 'data', 'pipeline' => $ops),
    array('timeout' => 100000000)
)

Notice that you must run the command over the $db and not your collection. 请注意,必须在$db而不是集合上运行命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM