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]

      

+3


source to share


1 answer


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.



+1


source







All Articles