Tomasz Gawlik
Tomasz Gawlik

Reputation: 333

Nest Elasticsearch search for null value

Using NEST (1.7.1) I have a specific search, where one field should match some collection of values OR this field should be null. Seems trival but I cannot create this query so the result would be the same as result when I'm not filtering my documents by this field.

Document:

public class Document
{
    ...
    [ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
    public string Field{ get; set; }
}

Query to match any of values from given collection:

Filter<Document>.Query(q =>  q.Terms(p=> p.Field, matchingCollection));

To match also those documents, which have NULL set as Field I was trying to add:

matchingCollection.Add(string.Empty);
matchingCollection.Add("NULL");

But without any success. Any ideas ? Thank you :)

Upvotes: 4

Views: 4193

Answers (2)

Russ Cam
Russ Cam

Reputation: 125488

For NEST 1.x, something like the following

client.Search<Document>(x => x
    .Query(q => q
        .Terms(f => f.Field, new [] { "term1", "term2", "term3" }) || q
        .Filtered(fq => fq
            .Filter(fqf => fqf
                .Missing(f => f.Field)
            )
        )
    )
);

which produces the following query

{
  "query": {
    "bool": {
      "should": [
        {
          "terms": {
            "field": [
              "term1",
              "term2",
              "term3"
            ]
          }
        },
        {
          "filtered": {
            "filter": {
              "missing": {
                "field": "Field"
              }
            }
          }
        }
      ]
    }
  }
}

For NEST 2.x onwards, something like

client.Search<Document>(x => x
    .Query(q => q
        .Terms(t => t
            .Field(f => f.Field) 
            .Terms("term1","term2","term3")
        ) || !q
        .Exists(e => e
            .Field(f => f.Field)
        )
    )
);

which produces the following query

{
  "query": {
    "bool": {
      "should": [
        {
          "terms": {
            "field": [
              "term1",
              "term2",
              "term3"
            ]
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "exists": {
                  "field": "field"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Upvotes: 4

Toshi
Toshi

Reputation: 2608

This is the best one I could find

 Filter<Document>.Query(q1 =>q1.Bool(q2 => q2
                               .MustNot(q3 => q3
                               .Exists(q4 => q4
                               .Field(q5 => q5.Field)))));

Hope there are better answers.

Upvotes: 0

Related Questions