使用 RestHighLevelClient 查询具有多个值的同一字段
query on same field with multiple values using RestHighLevelClient
我必须使用 Elasticsearch RestHighLevelClient 在 "url" 字段上 filter/query 多个 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
.
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/
和 [=17 时,它才会匹配=].
这种行为对于 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 模式之一匹配,如果结果也与内容匹配,则应提升结果。
为了实现这一点,您应该使用两个嵌套的 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 会将此查询解释为:
fetch documents that must match either url query #1
or url query #2
, and rank higher those that match wildcardQuery
defaultOperator
与这一切有什么关系?
.defaultOperator(Operator.OR)
实际上只是 Elasticsearch 试图混淆你:它与在逻辑 OR 中联合两个查询无关,而是 query string query:[=34= 的参数]
default_operator
(Optional, string) Default boolean logic used to interpret text in the query string if no operators are specified.
这个参数实际上是告诉Elasticsearch how to interpret the tokens inside the queryStringQuery()
that you pass. You can think about the string query as a query in Lucene query language.
希望对您有所帮助!
我必须使用 Elasticsearch RestHighLevelClient 在 "url" 字段上 filter/query 多个 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
.
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/
和 [=17 时,它才会匹配=].
这种行为对于 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 模式之一匹配,如果结果也与内容匹配,则应提升结果。
为了实现这一点,您应该使用两个嵌套的 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 会将此查询解释为:
fetch documents that must match either
url query #1
orurl query #2
, and rank higher those that matchwildcardQuery
defaultOperator
与这一切有什么关系?
.defaultOperator(Operator.OR)
实际上只是 Elasticsearch 试图混淆你:它与在逻辑 OR 中联合两个查询无关,而是 query string query:[=34= 的参数]
default_operator
(Optional, string) Default boolean logic used to interpret text in the query string if no operators are specified.
这个参数实际上是告诉Elasticsearch how to interpret the tokens inside the queryStringQuery()
that you pass. You can think about the string query as a query in Lucene query language.
希望对您有所帮助!