Building a filter dynamically in Elasticsearch
I am creating an API. I have id, name, price in elasticsearch. Client provides me with json input with filters applied.
Input 1: Below user filters records with id = 1 (integer)
{
"filters": {
"id":1
}
}
Input 2: User requests records using city = tokyo
{
"filters": {
"city":"tokyo"
}
}
Java code to process input and query elasticity search
filters = ipjson.path("filters");
Iterator<Entry<String, JsonNode>> ite = filters.fields();
while (ite.hasNext()) {
Entry<String, JsonNode> ele = ite.next();
String key = ele.getKey();
if (ele.getValue().isInt()) {
andFilter.add(FilterBuilders.termFilter(key, ele.getValue().asInt()))
} else if (ele.getValue().isTextual()) {
andFilter.add(FilterBuilders.termFilter(key, ele.getValue().textValue()));
}
}
For each key received in the filters, I check the data type of the input value.
I want to support all columns. I want a general solution without checking the input data type.
Entrance 3:
{
"filters": {
"city":"tokyo",
"id":3,
"price":134.45
}
}
Without any processing for each field and their data type, I want to query the above filters in elasticsearch using the java API. How should I do it?
Update:
Trying to send all string parameters to elastic search getting below exception
SearchParseException[[project][4]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"query":{"filtered":{"filter":{"and":{"filters":[{"term":{"id":"\"1\""}}]}}}}}]]]; nested: NumberFormatException[For input string: ""1""]; }
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.onFirstPhaseResult(TransportSearchTypeAction.java:233) ~[elasticsearch-1.4.1.jar:na]
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction$1.onFailure(TransportSearchTypeAction.java:179) ~[elasticsearch-1.4.1.jar:na]
at org.elasticsearch.search.action.SearchServiceTransportAction$23.run(SearchServiceTransportAction.java:565) ~[elasticsearch-1.4.1.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.7.0_60]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.7.0_60]
source to share
When you use termFilter for FilterBuilder, you do not need to specify values ββexplicitly as this supports all basic Java primitive types like (float, int, long, string, object). So just use FilterBuilders.termFilter (key, ele.getValue ()) and apache lucene engine will take care of the type.
source to share