使用RestHighLevelClient在具有多个值的同一字段上查询

时间:2020-04-15 04:52:50

标签: elasticsearch resthighlevelclient

我必须使用Elasticsearch RestHighLevelClient过滤/查询“ URL”字段上的多个URL。 我形成了如下查询,但它给出了0条记录。

query.must(QueryBuilders.queryStringQuery("http://localhost:8080/test/*")
                         .field("url")
                        .lenient(true)
                        .escape(true)
                        .analyzeWildcard(true)
                        .fuzziness(Fuzziness.ZERO)
                        .defaultOperator(Operator.AND)
                        .boost(1.0f));
query.must(QueryBuilders.queryStringQuery("http://www.bbc.com/*")
                     .field("url")
                    .lenient(true)
                    .escape(true)
                    .analyzeWildcard(true)
                    .fuzziness(Fuzziness.ZERO)
                    .defaultOperator(Operator.AND)
                    .boost(1.0f));

如果我更改为以下内容,它将仅给我匹配的记录URL http://localhost:8080/test/*,因为我为此设置了Operator.AND,并在URL http://www.bbc.com/*上查询了Operator.OR。 / p>

query.must(QueryBuilders.queryStringQuery("http://localhost:8080/test/*")
                         .field("url")
                        .lenient(true)
                        .escape(true)
                        .analyzeWildcard(true)
                        .fuzziness(Fuzziness.ZERO)
                        .defaultOperator(Operator.AND)
                        .boost(1.0f));
query.must(QueryBuilders.queryStringQuery("http://www.bbc.com/*")
                     .field("url")
                    .lenient(true)
                    .escape(true)
                    .analyzeWildcard(true)
                    .fuzziness(Fuzziness.ZERO)
                    .defaultOperator(Operator.OR)
                    .boost(1.0f));

因此,它忽略了http://www.bbc.com/*过滤器。

我在这里犯错了吗?如何在同一字段上编写多个查询?

1 个答案:

答案 0 :(得分:0)

bool查询中,您应该使用should而不是must

原始查询中会发生什么?

您执行的第一个查询实际上要求两个url值都出现在文档中:只有在同一文档中有url: http://localhost:8080/test/url: http://www.bbc.com/时,它才会匹配

此行为对于bool查询是正常的,并且不特定于我假设您正在使用的BoolQueryBuilder

如何对两个查询进行逻辑或运算?

实际上,您应该使用BoolQueryBuilder.should()将这两个查询放在逻辑或中:

query.should(QueryBuilders.queryStringQuery("http://localhost:8080/test/*")
                     .field("url")
                    .lenient(true)
                    .escape(true)
                    .analyzeWildcard(true)
                    .fuzziness(Fuzziness.ZERO)
                    .defaultOperator(Operator.AND)
                    .boost(1.0f));
query.should(QueryBuilders.queryStringQuery("http://www.bbc.com/*")
                 .field("url")
                .lenient(true)
                .escape(true)
                .analyzeWildcard(true)
                .fuzziness(Fuzziness.ZERO)
                .defaultOperator(Operator.AND)
                .boost(1.0f));

如何将其与查询的其他部分结合起来?

正如您在评论中指出的那样,您的查询实际上更加复杂:它必须与一种URL模式匹配,并且如果它们也与内容匹配,则应提高结果。

要实现此目的,您应该使用两个嵌套的布尔查询,如下所示:

BoolQueryBuilder urlQuery = BoolQueryBuilder();

urlQuery.should(QueryBuilders.queryStringQuery("http://localhost:8080/test/*")
                         .field("url")
                        .lenient(true)
                        .escape(true)
                        .analyzeWildcard(true)
                        .fuzziness(Fuzziness.ZERO)
                        .defaultOperator(Operator.AND)
                        .boost(1.0f));

urlQuery.should(QueryBuilders.queryStringQuery("http://www.bbc.com/*")
                     .field("url")
                    .lenient(true)
                    .escape(true)
                    .analyzeWildcard(true)
                    .fuzziness(Fuzziness.ZERO)
                    .defaultOperator(Operator.AND)
                    .boost(1.0f));

WildcardQueryBuilder wildcardQuery = QueryBuilderswildcardQuery("content", "anyt*");


// here `query` is your original bool query
query.must(urlQuery);
query.should(wildcardQuery);

Elasticsearch会将这个查询解释为:

获取必须匹配url query #1url query #2的文档,并将匹配wildcardQuery的文档排名更高

defaultOperator与所有这些有什么关系?

.defaultOperator(Operator.OR)实际上只是Elasticsearch试图使您感到困惑:它与将两个查询以逻辑OR组合在一起无关,而只是query string query的参数:

default_operator

(可选,字符串)如果未指定运算符,则用于解释查询字符串中文本的默认布尔逻辑。

此参数实际上告诉Elasticsearch how to interpret the tokens在内部{em> 您通过的queryStringQuery()。您可以将字符串查询视为Lucene query language中的查询。

希望有帮助!

相关问题