title: Elasticsearch - Filter where (one of nested array) and (all of nested array)
body: <p><strong><em>TL;DR</strong> - How do I check whether <strong>one-of</strong> and <strong>all-of</strong> a nested array meet specified criteria?</em></p>
  
  <p>I have a <code>document</code>. Each <code>document</code> has an array of nested <code>outer</code> objects, who themselves have a list of nested <code>inner</code> objects. I need to perform a filter for all documents where <strong>at least one of</strong> the document's <code>outer</code> nested objects match. When I say match, I mean that <strong>all</strong> the <code>outer</code> nested objects' <code>inner</code> objects match in some way. Here's an example mapping for reference;</p>
  
  <pre><code>{ "document" : {
      "properties" : {
        "name" : {
          "type" : "string"
        },
        "outer" : {
          "type" : "nested",
          "properties" : {
            "inner" : {
              "type" : "nested",
              "properties" : {
                "match" : {
                  "type" : "string",
                  "index" : "not_analyzed"
                },
                "type" : {
                  "type" : "string",
                  "index" : "not_analyzed"
                }
      }}}}}}
  }
  </code></pre>
  
  <p>If the document has no <code>outer</code>/<code>inner</code> objects it is considered to match. But to make things worse the inner objects need to be considered to match differently depending on the <code>type</code> in a kind of conditional logic manner (eg <code>CASE</code> in SQL). For example, if the <code>type</code> were the term <code>"Country"</code> then <code>inner</code> object would be considered to match if the <code>match</code> were a specified country code such as <code>ES</code>. A document may have <code>inner</code> objects of varying <code>type</code> and there is not guarantee that specific types will exist.</p>
  
  <p>Coming from a imperative (Java) programming background I am having incredible trouble figuring out how to implement this kind of filtering. Nothing I can think of even vaguely matches this behaviour. Thus far all I have is the filtered query;</p>
  
  <pre><code>"filtered" : {
        "query" : {
          "match_all" : { }
        },
        "filter" : {
          "bool" : {
            "should" : {
              "missing" : {
                "field" : "outer.inner.type"
              }
      }}}}
  }
  </code></pre>
  
  <p>So, the question is... </p>
  
  <p>How can I filter to documents who have <strong>at least one</strong> <code>outer</code> object which has <strong>all</strong> <code>inner</code> objects matching based on the <code>type</code> of <code>inner</code> object?</p>
  
  <p>Further details By Request -</p>
  
  <h2>Example Document JSON</h2>
  
  <pre><code>{
      "name":"First",
      "outer":[
          {
              "inner":[
                  {"match":"ES","type":"Country"},
                  {"match":"Elite","type":"Market"}
              ]
          },{
              "inner":[
                  {"match":"GBR","type":"Country"},
                  {"match":"1st Class","type":"Market"},
                  {"match":"Admin","type":"Role"}
              ]
          }
      ],
      "lockVersion":0,"sourceId":"1"
  }
  </code></pre>
  
  <p>The above example should come through the filter if we were to provide <code>"1st Class"</code> market <strong>and</strong> the country <code>"GRB"</code> because the second of the two <code>outer</code> objects would be considered a match because both <code>inner</code> objects match. If, however, we provided the country country <code>"GRB"</code> and the market <code>"Elite"</code> then we would not have this document returned because neither of the <code>outer</code> objects would have bother of their <code>inner</code> objects match in their entirety. If we wanted the second <code>outer</code> object to match then all three <code>inner</code> would need to match. Take note that there is an extra <code>type</code> in the third <code>inner</code>. This leads to a situation where <strong>if</strong> a type exists <strong>then</strong> it needs to have a match for it <strong>else</strong> it doesn't need to match because it is absent. </p>