Search code examples
javaelasticsearchopensearch

Is it possible to create a map in runtime mode, which will be filled in passing through all documents and returned at the end ES


For ex: I have 2 documents with this body:

{
  "id": "doc_one",
  "name": "test_name",
  "date_creation": "some_date_cr_1",
  "date_updation": "some_date_up_1"
}

And the second doc:

{
  "id": "doc_two",
  "name": "test_name",
  "date_creation": "some_date_cr_2",
  "date_updation": "some_date_up_2"
}

What I want to do: to create two runtime field or Map('data_creation',count_of_doc_where_field_not_null_AND_the_condition_is_met).

For ex: I've got the 1st doc, there is date_creation IS NOT NULL and the condition startDate<=date_creation<=endDate is met, so, I create some field count = 0 and when I've got this case I do count++. When I will get all the docs I will set finally count value from map as result: Map('data_creation',final_count) and the same for another field but in the same map.

I tried to use script, but there is return Map for each doc, for ex:

{
            "_index": "my_index_001",
            "_type": "_doc",
            "_id": "1",
            "_score": 1.0,
            "fields": {
                "my_doubled_field": [
                    {
                        "NEW": 2
                    }
                ]
            }
        },
        {
            "_index": "my_index_001",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.0,
            "fields": {
                "my_doubled_field": [
                    {
                        "NEW": 2
                    }
                ]
            }
        }

Solution

  • I have index below 3 documents to index where one document dont have date_creation field:

    POST sample/_doc
    {
      "id": "doc_two",
      "name": "test_name",
      "date_updation": "some_date_up_2"
    }
    
    POST sample/_doc
    {
      "id": "doc_one",
      "name": "test_name",
      "date_creation": "some_date_cr_1",
      "date_updation": "some_date_up_1"
    }
    
    POST sample/_doc
    {
      "id": "doc_two",
      "name": "test_name",
      "date_creation": "some_date_cr_2",
      "date_updation": "some_date_up_2"
    }
    
    

    Now you can use filter aggregation from elasticsearch as shown below:

    {
      "size": 0,
      "aggs": {
        "date_creation": {
          "filter": {
            "range": {
              "date_creation": {
                "gte": "2020-01-09T10:20:10"
              }
            }
          }
        },
        "date_updation": {
          "filter": {
            "range": {
              "date_updation": {
                "gte": "2020-01-09T10:20:10"
              }
            }
          }
        }
      }
    }
    

    Response:

    "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : null,
        "hits" : [ ]
      },
      "aggregations" : {
        "date_updation" : {
          "meta" : { },
          "doc_count" : 3
        },
        "date_creation" : {
          "meta" : { },
          "doc_count" : 2
        }
      }
    

    You can see date_updation field is available in 3 doc so it is showing count as 3 and date_creation field is available in 2 doc so it is showing count as 2.