title: MongoDB, conditional upserts or updates
body: <p>When using MongoDB I'm currently doing a conditional upsert as a part of an aggregation process, on the form (simplified alot):  </p>
  
  <pre><code>db.dbname.update({attr1 : value1, attr2 : value2},
                   {"$inc" : { avg : current_value, nr : 1}},
                   false (multi), true (upsert))
  </code></pre>
  
  <p>But I want to able to keep a maximum (and minimum) value as well, without having to retrieve the document. Something along the lines of:</p>
  
  <pre><code>db.dbname.update({ attr1 : value1, attr2 : value2},
                   {"$inc" : { avg : current_value, nr : 1},
                    "$setIfBigger" : { max : current_value}},
                   false (multi), true (upsert))
  </code></pre>
  
  <p>Is this possible in an efficient way?</p>
  
  <p>My current, extremely inefficient, solution is that I check for a current aggregation document, and if it exists I update the values accordingly, and if it doesn't I create a new document. Example (again, simplified alot, but the essence is there):</p>
  
  <pre><code>var obj = db.dbname.findOne({attr1 : value1, attr2 : value2},{_id:1});
  if (obj != null) {
     db.dbname.update({attr1 : value1, attr2 : value2},
                      {"$inc" : { avg : current_value, nr : 1},
                       "$set" : { max : (obj.max &gt; current_value ? obj.max : current_value}},
                      false (multi), true (upsert));
  } else {
     db.dbname.save({attr1 : value1, attr2 : value2, 
                     avg : current_value, nr : 1,
                     max : current_value});
  }
  </code></pre>
  
  <p>The actual program is written in Java and uses the mongo-API, and the aggregation process is quite complex and uses composition techniques way beyond Javascript to communicate with other servers, ergo mapreduce is not an option. Finally the end result is quite a humongous set of simple values which I want to store in the most effecient way and also store precalculated averages, maximums and minimums of certain combinations.  </p>
  
  <p>One solution is creating unique function-objects in JS for every single update, which I believe is not an efficient way?</p>
  
  <p>The main objective is to decrease the time taken to perform an aggregation of this type, bandwidth usage is secondary.</p>