How to add criteria dynamically while searching against elasticsearch

I have a big document with a requirement to dynamically search
E.g. Student

{
id,
name,
Address,
Associated_Subjects
phone,
home_phone,
mobile,
year,
dob,
geolocation:(lat/long)
height
.
.
.
etc
}

However I have certain fields to be searched with static criteria e.g. year as 2020,geoLocation within 20 miles etc
and some criteria to be added on various conditions e.g. year <2020 and height >4 feet (this is just an example)

Not sure how do I cater this requirement ie. Either use a SQL template as below and have place holder to inject (append) additional criterias in it through
java code or use RestHighLevelClient (Could not find such a realistic example through like relational ORM criteria api like Specification)

Here is how my template will look like and will be formed on the fly as per request

    "bool": {
        "must": [
           
            {
                "match": {
                    "Associated_Subjects": $SUBJECT$
                }
            }
        ],
        "filter": [
			$DYNAMIC_PLACEHOLDERS$
            {
                "geo_distance": {
                    "distance": "$DISTANCE_RADIUS$",
                    "location": {
                        "lat": $LATITUDE$,
                        "lon": $LONGITUDE$
                    }
                }
            },
            {
                "range" : {
                    "dob": {
                        "gte": "$DOB$"
                    }
                }
            }
        ]
    }
}

e.g. $DYNAMIC_PLACEHOLDERS$ will be added as below on the fly
{
"range" : {
"age": {
"gte": "$DOB$"
}
}
},
My Question : Is having such template and modifying as per request is good idea or is there any better way to deal with it and what about the performance is there any best practices in Elasticsearch ?

Elasticsearch does not have if/else in their templating engine. Only if a field is set you could add a block to the query.

If it is a dynamic query with dynamic fields and conditions I would recommend using it in code somewhere and build up the query there. But maybe I am getting the question wrong..

For the Elastic search document definition below
{
id,
name,
Address,
Associated_Subjects
phone,
home_phone,
mobile,
year,
dob,
geolocation:(lat/long)
height
gender
.
.
.
etc
}

e.g. in Above document I need to search on the fly
e.g. If gender =Male then height >=5 feet
& if gender =FeMale then height >=4 feet

However rest of the Query fields remain same & vary based on gender as below

I would have QUERY_TEMPLATE as below
E.g.
"bool": {
"must": [

            {
                "match": {
                    "Associated_Subjects": $SUBJECT$
                }
            }
        ],
        "filter": [
			$DYNAMIC_PLACEHOLDERS$
            {
                "geo_distance": {
                    "distance": "$DISTANCE_RADIUS$",
                    "location": {
                        "lat": $LATITUDE$,
                        "lon": $LONGITUDE$
                    }
                }
            },
            {
                "range" : {
                    "dob": {
                        "gte": "$DOB$"
                    }
                }
            }
        ]
    }
}

Here based on gender
e.g. if Male DYNAMIC_PLACEHOLDERS will be replaced with

{
				"range": {
					"LATITUDE": {
						"gte": 5
					}
				}
},

AND
e.g. if FeMale DYNAMIC_PLACEHOLDERS will be replaced with

{
				"range": {
					"LATITUDE": {
						"gte": 4
					}
				}
},

Here replacing DYNAMIC_PLACEHOLDERS with above range constraint I am planning to handle in java code.Will this be a good idea and efficient way or is there
any better way to do it as I have many such dynamic conditions will require to be added based on request parameters ?

Are these values always present? What you could do is creating a search template and use parameters to change those values. Your application triggers the search. So in that case you can use the template and set the right values to the params.

A link to the documentation about that:

It comes to this workflow:

  1. Create the template
POST _scripts/<templateid>
{
  "script": {
    "lang": "mustache",
    "source": {
      "query": {
        "match": {
          "title": "{{query_string}}"
        }
      }
    }
  }
}

The name between {{ and }} will be the paramaters.

  1. Fire the search with the template id
GET _search/template
{
  "id": "<templateid>", 
  "params": {
    "query_string": "search for these words"
  }
}

So the latitude value can be a parameter same like the origin point and the radius, next to the subjects.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.