title: MongoDB aggregate by field exists
body: <p>I have a hard time believing this question hasn't been asked and answered somewhere already, but I can't find any trace of it.</p>
  
  <p>I have a MongoDB aggregation query that needs to group by a boolean: the existence of another field.</p>
  
  <p>For example let's start with this collection:</p>
  
  <pre class="lang-js prettyprint-override"><code>&gt; db.test.find()
  { "_id" : ObjectId("53fbede62827b89e4f86c12e"),
    "field" : ObjectId("53fbede62827b89e4f86c12d"), "name" : "Erik" }
  { "_id" : ObjectId("53fbee002827b89e4f86c12f"), "name" : "Erik" }
  { "_id" : ObjectId("53fbee092827b89e4f86c131"),
    "field" : ObjectId("53fbee092827b89e4f86c130"), "name" : "John" }
  { "_id" : ObjectId("53fbee122827b89e4f86c132"), "name" : "Ben" }
  </code></pre>
  
  <p>2 documents have "field", and 2 don't.
  Note that each value of "field" may be different; we just want to group on its existence (or non-nullness works for me too, I don't have any null values stored).</p>
  
  <p>I've tried using $project, but $exists doesn't exist there, and $cond and $ifNull haven't helped me.  The field always appears to exist, even when it doesn't:</p>
  
  <pre class="lang-js prettyprint-override"><code>&gt; db.test.aggregate(
    {$project:{fieldExists:{$cond:[{$eq:["$field", null]}, false, true]}}},
    {$group:{_id:"$fieldExists", count:{$sum:1}}}
  )
  { "_id" : true, "count" : 4 }
  </code></pre>
  
  <p>I would expect the following much simpler aggregate to work, but for some reason $exists isn't supported in this way:</p>
  
  <pre><code>&gt; db.test.aggregate({$group:{_id:{$exists:"$field"}, count:{$sum:1}}})
  assert: command failed: {
    "errmsg" : "exception: invalid operator '$exists'",
    "code" : 15999,
    "ok" : 0
  } : aggregate failed
  Error: command failed: {
    "errmsg" : "exception: invalid operator '$exists'",
    "code" : 15999,
    "ok" : 0
  } : aggregate failed
      at Error (&lt;anonymous&gt;)
      at doassert (src/mongo/shell/assert.js:11:14)
      at Function.assert.commandWorked (src/mongo/shell/assert.js:244:5)
      at DBCollection.aggregate (src/mongo/shell/collection.js:1149:12)
      at (shell):1:9
  2014-08-25T19:19:42.344-0700 Error: command failed: {
    "errmsg" : "exception: invalid operator '$exists'",
    "code" : 15999,
    "ok" : 0
  } : aggregate failed at src/mongo/shell/assert.js:13
  </code></pre>
  
  <p>Does anyone know how to get the desired result from a collection like this?</p>
  
  <p>Expected result:</p>
  
  <pre class="lang-js prettyprint-override"><code>{ "_id" : true, "count" : 2 }
  { "_id" : false, "count" : 2 }
  </code></pre>