How to get Elastic Search aggregation to mirror the query filtering logic?
<p>On our site we allow users to filter Elastic Search results with a set of filters divided into categories:</p>

<pre><code>A
  A1
  A2
  ...
B
  B1
  B2
  B3
  ...
</code></pre>

<p>These are just matching on literal tags that can appear in a field of the document, like:</p>

<pre><code>{ tags: ["A1", "B1", "B2"] }
</code></pre>

<p>Our existing query joins all the filter terms under AND, so if the user selects <code>A1</code>, <code>B1</code>, and <code>B2</code>, we filter by <code>(A1 AND B1 AND B2)</code>.</p>

<p>We want to change this to "OR within each filter category", and "AND across categories", so that you'd get: <code>(A1) AND (B1 OR B2)</code>.</p>

<p>Now, the wrinkle: we also use a "terms" aggregation on the "tags" field to predict how many items would come back from applying the next filter. On our UI this looks like:</p>

<pre><code>A
  A1   12   # If the user adds the A1 filter, there'll be 12 results.
  A2   3    # etc.
  ...
B
  B1   5
  B2   0
  B3   2
  ...
</code></pre>

<p>Here, changing the filter logic to AND/OR breaks the counts that come back from the "terms" aggregation, because the terms aggregation is still predicting <code>A1 AND B1 AND B2</code>. Adding <code>B3</code> would get us <code>A1 AND B1 AND B2 AND B3</code> and thus narrow the counts from the aggregations, whereas it would actually widen the scope of the results (we'd want <code>(A1) AND (B1 OR B2 OR B3)</code>).</p>

<p>Is there a way to express this in aggregations so that the filtering logic and the aggregation counts match?</p>