如何在PHP中批量upsert mongodb?

时间:2011-04-17 03:58:09

标签: php performance mongodb

我目前有一些代码需要为每个用户为成千上万的用户执行多次更新,根据他们为了跟踪正在执行的操作而采取的操作来递增计数器。每个动作都包含需要更新计数的子动作。这些需要在白天进行跟踪。

所以我存储“动作”:“actionName”,“day”:day,“count”:count,表示每天的动作(例如从外部网页传入,开始游戏,退出游戏,与许多游戏的游戏名称。)

每天我都会添加几千行(每个独特动作一行),每天更新数十万次以增加计数。

相关代码如下(创建未包含的操作数组)。

$m = new Mongo();
$db = $m->actionsDB;
$collection = $db->action_count;

foreach ($arr as $action) {
    $collection->update(array("action" => $action, "day" => $day),array('$inc' => array("count" => 1)),array("upsert" => true));)
}
$collection->ensureIndex(array("action" => 1, "day" => -1));

对动作和子动作进行的一系列更新的示例如下: startGame,20110417; startGameZork,20110417; startGameZorkWindows,20110417

问题似乎是在服务器上运行此代码时,shell中的mongo命令排队等待。

目前我不确定为什么,我想每秒有这么多更新可能会出现性能问题。

我想知道的是如何提高性能?我对mongo很新,所以不完全确定有哪些选项。我查看了PHP的batchInsert,但是我看不到任何提到的batchUpdate(因此不是更新,而是创建一个包含我当前更新的所有数据的数组,然后在一次数据库中执行batchUpdate)。

Mongo驱动程序版本是1.2.0,因此默认情况下是持久连接。

编辑:db.serverStatus()在每秒~1600次更新(30秒)之前,期间和之后。 Test Data

2 个答案:

答案 0 :(得分:1)

没有用于更新/ upsert的内置批处理。您只能通过调整查询表达式并添加一些“以某种方式”模拟“批处理”的进一步过滤器来限制要更新的文档。 MongoDB在这里不会帮到你。更新/ Upserts是一个或全部。

答案 1 :(得分:1)

如果您有机会将数据存储在文件(json或csv)中,则可以尝试使用命令行mongoimport实用程序插入数据。

通过这种方式,您可以使用--upsert标志来更新/插入文件(如果已存在/新文件)

例如来自PHP:

exec("mongoimport --db <bdname> --collection <collection_name> --jsonArray --upsert --file $data_file");