Search code examples
javaelasticsearchelasticsearch-plugin

How to add If-else condition in same index with different documents by "type" (individually added in doc) in elasticsearch query?


I am using elastic search 1.6 with java. Actually, I am new in elastic queries. in the learning phase. Trying some advanced conditions.

I created an index "IndexABCD" in which I have two different document & identified by their "type" field. Below I sample document present in elastic.

For example -

Doc1
{
    "id":"DS-1",
    "type":"DATASOURCE",
    "name":"test1",
    "category":"cat1",
    "subCategory":"subcat1"
}

Doc2
{
    "id":"FL-1",
    "type":"FLOW",
    "name":"test1"
}

Doc3
{
    "id":"DS-2",
    "type":"DATASOURCE",
    "category":"cat1",
    "subCategory":"subcat1",
    "name":"test2"
}

Doc4
{
    "id":"FL-3",
    "type":"FLOW",
    "name":"test3"
}

How can I add following if-else condition which gives an expected output?

if(type=="Datasource"){
    category = "cat1";
    subCategory = "subCat1";
}

if(type=="DATASOURCE" && type="FLOW"){
    category = "cat1";
    subCategory = "subCat1";
    &
    don't apply category & subcategory on type FLOW 
}    

Below query used in my cases but I didn't found the perfect solution for my scenario.
In the query, If I gave DATASOURCE result like - 2 records in which contains category & subcategory. OR which query will be fit in a current query?

Current Query:-    
{
  "query":  
 {
  "filtered" : {
    "query" : {
      "bool" : {
        "must" : [  {
          "bool" : {
            "should" : {
              "terms" : {
                "datasource_and_flow.type" : [ "DATASOURCE" ]
              }
            }
          }
        },{
          "query_string" : {
            "query" : "test*",
            "default_field" : "datasource_and_flow.name"
          }
        } ],
        "should": [
           {
          "bool" : {
            "should" : {
              "terms" : {
                "category" : [ "cat1" ]
              }
            }
          }
        }, {
          "bool" : {
            "should" : {
              "terms" : {
                "sub_category" : [ "subcat2" ]
              }
            }
          }
        }
        ]
      }
    },        
    "filter" : {      
    }
  }
},
  "from": 0,
  "size": 10,
  "sort": [],
  "facets": {}, "aggs": {
    "datasource_and_flow.type": {
      "terms": {
        "field": "type"
      }
    }  
    }
}

If We add

datasource_and_flow.type = [ "DATASOURCE","FLOW"]

now we want

total records = 2 records + flow by name "test*"

but current query give DATASOURCE type only not getting record from FLOW

For your info - index json mapping - click here for JSON Mapping file


Solution

  • The query below first filters all docs by "test" keyword, then it applies a should clause where it checks for any 1 criteria out of 2 i.e (DATASOURCE + cat1 + subcat2) OR (FLOW)

    GET _search
    {
      "from": 0,
      "size": 20,
      "query": {
        "query_string": {
          "query": "test*",
          "default_field": "name"
        },
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "type": "DATASOURCE"
                    }
                  },
                  {
                    "term": {
                      "category": "cat1"
                    }
                  },
                  {
                    "term": {
                      "sub_category": "subcat1"
                    }
                  }
                ]
              }
            },
            {
              "term": {
                "type": "FLOW"
              }
            }
          ],
          "minimum_number_should_match": 1
        }
      }
    }