简体   繁体   English

Elasticsearch中的动态过滤器构建

[英]Dynamic Filter Building in Elasticsearch

I am building API. 我正在构建API。 I have id,name,price in elasticsearch. 我在elasticsearch中有id,name,price。 Client provides me input json with filters to be applied. 客户端为我提供了输入json和要应用的过滤器。

Input 1: Below user is filtering records with id=1 (integer) 输入1:用户正在过滤id = 1(整数)的记录

{
    "filters": {
        "id":1
    }

}

Input 2: User is querying for records with city=tokyo 输入2:用户正在查询city = tokyo的记录

{
    "filters": {
        "city":"tokyo"
    }

}

Java code for handling inputs and querying to elastic search 用于处理输入和查询弹性搜索的Java代码

        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 filters, I am checking data type of input value. 对于过滤器中收到的每个密钥,我正在检查输入值的数据类型。

I want to support all columns. 我想支持所有列。 I want a generic solution without checking for input data type. 我想要一个通用的解决方案,而不检查输入数据类型。

Input 3: 输入3:

{
        "filters": {
            "city":"tokyo",
            "id":3,
            "price":134.45
        }

}

Without any handling for each field vs their data type, I want to query above filters in elasticsearch with java API. 没有对每个字段与其数据类型进行任何处理,我想使用java API在elasticsearch中查询上面的过滤器。 How would I do that? 我该怎么办?

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]

When you use termFilter for FilterBuilder you dont need to specify the values explicitly as this supports all the basic primitive Java types such as (float,int,long,string,object). 当您对FilterBuilder使用termFilter时,您不需要显式指定值,因为它支持所有基本原始Java类型,例如(float,int,long,string,object)。 So just use FilterBuilders.termFilter(key, ele.getValue()) and apache lucene engine takes care of the type. 所以只需使用FilterBuilders.termFilter(key,ele.getValue())和apache lucene引擎来处理类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM