title: Is there a way to apply an arbitrary condition to a MongoDB aggregation?
body: <p>I have a MongoDB database where people can enter relatively arbitrary search conditions (in this case they are vetted, but not restricted conceptually). An example of a condition a user could specify may look like:</p>
  <pre><code>{&quot;$and&quot;: [
    {&quot;details.vulns&quot;: &quot;cve-2019-19781&quot;},
  ]}
  </code></pre>
  <p>This works well for searching, however, I want to be able to also generate statistics based on older data, for which I use an aggregation that looks something like:</p>
  <pre><code>db.hosts.aggregate([
      {&quot;$sort&quot;: {&quot;timestamp&quot;: 1}},
      {&quot;$addFields&quot;: {
          &quot;condition&quot;: {$cond: [
              {&quot;$and&quot;: [
                  {&quot;details.vulns&quot;: &quot;cve-2019-19781&quot;},
              ]},
              1,
              0,
          ]}
      }},
      {&quot;$project&quot;: {
          &quot;ip&quot;:        &quot;$ip&quot;,
          &quot;timestamp&quot;: &quot;$timestamp&quot;,
          &quot;condition&quot;: &quot;$condition&quot;,
      }},
  ]);
  </code></pre>
  <p>The problem with such a query is MongoDB does not seem to allow using a $cond with something like <code>$details.vulns</code>. I understand a standard approach would be to unwind, however, due to the conditions being not known before my code executes, I have no way to know what fields to unwind unless I re-implement a MongoDB parsing engine in my own code.</p>
  <p>To demonstrate the issue more clearly, here is some example data. Keep in mind that this is simplified -- the real data contains many different fields that I may wish to query against, hence the above statements about unwind not being a satisfactory solution:</p>
  <pre><code>// Objects
  { &quot;_id&quot; : ObjectId(&quot;5cfc73657e2438b115888d1b&quot;), &quot;ip&quot; : NumberLong(&quot;12345&quot;), &quot;timestamp&quot; : ISODate(&quot;2019-06-09T02:45:45Z&quot;), &quot;vulns&quot; : [ &quot;cve-2019-19781&quot; ] },
  { &quot;_id&quot; : ObjectId(&quot;5d04c5497e2438b115b06659&quot;), &quot;ip&quot; : NumberLong(&quot;12345&quot;), &quot;timestamp&quot; : ISODate(&quot;2019-06-15T10:13:33Z&quot;), &quot;vulns&quot; : [ &quot;&quot; ] },
  { &quot;_id&quot; : ObjectId(&quot;5d108c52211d917c6ff48bfd&quot;), &quot;ip&quot; : NumberLong(&quot;12345&quot;), &quot;timestamp&quot; : ISODate(&quot;2019-06-24T08:37:31Z&quot;), &quot;vulns&quot; : [ &quot;cve-2019-19781&quot;, &quot;other-vuln&quot; ] },
  
  // Desired output from aggregate
  {&quot;ip&quot; : NumberLong(&quot;12345&quot;), &quot;timestamp&quot; : ISODate(&quot;2019-06-09T02:45:45Z&quot;), &quot;condition&quot;: 1 },
  {&quot;ip&quot; : NumberLong(&quot;12345&quot;), &quot;timestamp&quot; : ISODate(&quot;2019-06-15T10:13:33Z&quot;), &quot;condition&quot;: 0 },
  {&quot;ip&quot; : NumberLong(&quot;12345&quot;), &quot;timestamp&quot; : ISODate(&quot;2019-06-24T08:37:31Z&quot;), &quot;condition&quot;: 1 },
  </code></pre>
  <p>Is there an alternative approach here I am missing, or does MongoDB simply lack the ability to apply a search clause during an aggregation?
  If there was a slow way of doing it, I would be fine with that.</p>