title: Querying array of strings by array of strings in elasticsearch.net
body: <p>I'm using elasticsearch.net library in C# and I'm trying to query for objects matching specified filter. </p>
  
  <p>I would like the query to return objects where at least one of input names from filter exists in object's Names collection.</p>
  
  <p>The problem is that I always get 0 hits as result with this query, even tho I am certain that data matching specified filter does exist in the database and I would love to find out what's wrong with my query...</p>
  
  <p>The model: </p>
  
  <pre><code>public class A
  {
      public int AId { get; set; }
      public IEnumerable&lt;string&gt; Names { get; set; }
  }
  </code></pre>
  
  <p>The filtering object:</p>
  
  <pre><code>public class Filter
  {
      public IEnumerable&lt;string&gt; NamesToSearch { get; set; }
  }
  </code></pre>
  
  <p>The method for querying data:</p>
  
  <pre><code>public async Task&lt;IEnumerable&lt;A&gt;&gt; GetFilteredData(Filter filter)
  {
      var query = await _elasticClient.SearchAsync&lt;A&gt;(x =&gt; x.Query(q =&gt; q.Terms(a =&gt; a.Names, filter.NamesToSearch))
                                                              .Fields(a =&gt; a.AId, a =&gt; a.Names));
  
      return query.Hits
                  .Select(x =&gt; new A
                                  {
                                      AId = x.Fields.FieldValues&lt;A, int&gt;(a =&gt; a.AId)[0]
                                  })
                  .ToList();
  }
  </code></pre>
  
  <p>I have also tried following query, but it didn't yield expected result neither:</p>
  
  <pre><code>var query = await _elasticClient.SearchAsync&lt;A&gt;(x =&gt; x.Query(q =&gt; q.Nested(n =&gt; n.Filter(f =&gt; f.Terms(y =&gt; y.Names, filter.NamesToSearch))))
                                                                .Fields(a =&gt; a.AId, a =&gt; a.Names));
  </code></pre>
  
  <p><strong>SOLUTION WHICH WORKED FOR ME:</strong></p>
  
  <p>I have upgraded a bit code from <a href="https://stackoverflow.com/a/36377068/4775097">Sławomir Rosiek's answer</a> to actually compile using ElasticSearch.net 1.7.1 and be type-safe (no references to field name by string) and ended up with following extension method, which worked like a charm for my scenario:</p>
  
  <pre><code>public static QueryContainer MatchAnyTerm&lt;T&gt;(this QueryDescriptor&lt;T&gt; descriptor, Expression&lt;Func&lt;T, object&gt;&gt; field, object[] values) where T : class, new()
  {
      var queryContainer = new QueryContainer();
  
      foreach (var value in values)
      {
          queryContainer |= descriptor.Term(t =&gt; t.OnField(field).Value(value));
      }
  
      return queryContainer;
  }
  </code></pre>
  
  <p>and usage:</p>
  
  <pre><code>var query = await _elasticClient.SearchAsync&lt;A&gt;(x =&gt; x.Query(q =&gt;
                                                                  q.Bool(b =&gt;
                                                                      b.Should(s =&gt; s.MatchAnyTerm(a =&gt; a.Names, filter.NamesToSearch.ToArray()))
                                                                          .Fields(a =&gt; a.AId, a =&gt; a.Names));
  </code></pre>