title: How to batch upsert mongodb in PHP?
body: <p>I currently have some code which needs to perform multiple updates per user for thousands of users, incrementing a counter depending on an action they've taken in order to track what actions are being performed. Each action consists of subactions which need to have the count updated too. These need to be tracked by day.</p>
  
  <p>So I am storing "action":"actionName", "day":day, "count": count, for actions per day (e.g. incoming from outside web page, start game, stop game by exiting, concatenated with the game name for a lot of games).</p>
  
  <p>Each day I get a few thousand rows (one per unique action) added which are updated a few hundred thousand times each day to increase the count.</p>
  
  <p>The relevant code is as follows (creating array of actions not included).</p>
  
  <pre><code>$m = new Mongo();
  $db = $m-&gt;actionsDB;
  $collection = $db-&gt;action_count;
  
  foreach ($arr as $action) {
      $collection-&gt;update(array("action" =&gt; $action, "day" =&gt; $day),array('$inc' =&gt; array("count" =&gt; 1)),array("upsert" =&gt; true));)
  }
  $collection-&gt;ensureIndex(array("action" =&gt; 1, "day" =&gt; -1));
  </code></pre>
  
  <p>An example of the series of updates made on an action and subactions would be:
  startGame, 20110417;
  startGameZork, 20110417;
  startGameZorkWindows, 20110417</p>
  
  <p>The problem seems to be that with this code running on the server, mongo commands in the shell get queued up.</p>
  
  <p>Currently I'm unsure as to why, I guess there may be a performance issue with so many updates per second.</p>
  
  <p>What I am wondering is how can I increase performance? I'm pretty new to mongo, so not entirely sure what options are available. I looked at PHP's batchInsert but I can't see any mention of doing batchUpdate (so instead of updating, creating an array holding all the data I currently update then doing a batchUpdate in a single trip to the DB).</p>
  
  <p>Mongo driver version is 1.2.0, so persistent connections are by default.</p>
  
  <p>Edit: db.serverStatus() before, during and after on ~1600 updates per second (30 seconds). <a href="http://textbin.com/8103o" rel="noreferrer">Test Data</a></p>