Search code examples
elasticsearchnestelasticsearch-netelasticsearch-dsl

ElasticSearch query for documents based on active date element in array


I have an ElasticSearch index, where the data is indexed as I've copy-pasted in the bottom.

Idea is that it has documents, and the "official name" of the document, is in an array. This is because the official name of the document is valid for a period (ie between 2014 and 2015 name was X, and between 2016 and 2018 it is Y).

What I want is a simple query, which finds the documents based on the name attribute, but where it is valid today.

The document map:

"Company": {
        "properties": {
          "vatNumber": {
            "type": "string"
          },
          "names": {
            "type": "nested",
            "include_in_parent": true,
            "properties": {
              "name": {
                "type": "string"
              },
              "period": {
                "properties": {
                  "validFrom": {
                    "type": "date",
                    "format": "dateOptionalTime"
                  },
                  "validTo": {
                    "type": "date",
                    "format": "dateOptionalTime"
                  }
                }
              },
              "lastUpdated": {
                "type": "date",
                "format": "dateOptionalTime"
              }
            }
          }}}

My attempt:

I use NEST (.NET client). I assume there are 2 overall "challenges":

  1. I need to refer a property in an array (the name)
  2. I need to make a check that validTo is indeed null (and ignore the other entities in the array)

However, after searching around, I'm quite lost on these two!


Solution

  • What you are looking for is nested queries where you can specify path to nested field (names.name and names.period.validTo here). To check a field is null you use the exists query with in a must_not clause of a bool query. Here is a sample

    GET /_search

    {
        "query": {
            "nested" : {
                "path" : "names",
                "query" : {
                    "bool" : {
                        "must":{
                            "term": {
                                "names.name": "Lars"
                            }
                        },
                        "must_not" :{
                            "exists": {
                                "field": "names.period.validTo"
                            }
                        }
                    }
                }
            }
        }
    }