使用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));

如果我更改为以下内容,它将只给我匹配的记录urlhttp://localhost:8080/test/*,因为我将Operator.AND设置为该值,并将urlhttp://www.bbc.com/*查询为Operator.OR

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/*滤波器。

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

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

原始查询中发生了什么

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

这种行为对于bool查询来说是正常的,并且不是特定于我认为您正在使用的BoolQueryBuilder

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

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

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模式匹配,如果结果也与内容匹配,则应该提高结果。

为了实现这一点,您应该使用两个嵌套的bool查询,如下所示:

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中合并两个查询无关,而是查询字符串查询的一个参数:

默认操作员

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

这个参数实际上告诉Elasticsearch如何解释您传递的queryStringQuery()内部的令牌。您可以将字符串查询视为Lucene查询语言中的查询。

希望能有所帮助!

相关内容

  • 没有找到相关文章

最新更新