【问题标题】:Dynamic Filter Building in ElasticsearchElasticsearch 中的动态过滤器构建
【发布时间】:2015-08-29 22:51:17
【问题描述】:

我正在构建 API。我在 elasticsearch 中有 id、name、price。客户端为我提供了输入 json 以及要应用的过滤器。

输入 1:下面的用户正在过滤 id=1(整数)的记录

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

}

输入 2:用户正在查询 city=tokyo 的记录

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

}

用于处理输入和查询弹性搜索的 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()));
            }


        }

对于过滤器中收到的每个键,我正在检查输入值的数据类型。

我想支持所有列。我想要一个不检查输入数据类型的通用解决方案。

输入 3:

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

}

在没有对每个字段与其数据类型进行任何处理的情况下,我想使用 java API 在 elasticsearch 中查询上述过滤器。我该怎么做?

更新:

尝试将所有字符串参数发送到弹性搜索,低于异常

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]

【问题讨论】:

  • 为什么需要将值转换为具体的数据类型?您可以将它们保留为字符串。
  • 如果我不转换或保留它的字符串,那么它会在结果中抛出异常。数据类型不匹配。
  • 请发布您的异常,也许您需要在索引之前配置您的索引。
  • 我已经更新了我的问题,但我在 id 查询中传递字符串时遇到了异常
  • @KunalPradman 您可以发布导致此异常的代码吗?它似乎与上面的代码不同。从错误来看,您似乎有不需要存在的双引号。

标签: java elasticsearch playframework-2.0 elasticsearch-plugin


【解决方案1】:

当您为 FilterBuilder 使用 termFilter 时,您不需要显式指定值,因为它支持所有基本的基本 Java 类型,例如 (float,int,long,string,object)。所以只需使用 FilterBuilders.termFilter(key, ele.getValue()) 和 apache lucene 引擎来处理类型。

【讨论】:

  • 我需要在弹性搜索中为此配置什么吗?我试过了,但抛出了数据类型异常
  • 我已经更新了我的问题,但我在 id 查询中传递字符串时遇到了异常
  • ""1"" 输入中的额外引号使 lucene 难以转换为已知的数据类型。
  • 但此输入来自客户端,即 PHP、Android、Postman。他们将 json 发布到 Java API,Java API 动态构建 ES 查询。我如何实现它?
  • 我认为您可以使用 Guava 插件并删除字符串的额外引号。例如:CharMatcher.is('\"').trimFrom("stringvalue");
猜你喜欢
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
相关资源
最近更新 更多