elasticsearch 弹性搜索查询行为
我对elasticsearch有两个不同的查询。这两个查询之间的区别在于,第一个查询在一个boolean-should查询中获得了两个搜索条件,第二个查询将其拆分为两个单独的bool-should查询。第一个返回预期的响应,但第二个与任何文档都不匹配,即使存在包含这两个条件的文档。如果我重构第二个,使两个拆分的bool-should查询被bool-should-query封装,它将返回预期的响应,就像查询1一样 问题是为什么查询2不像1和3那样返回响应?我错过什么了吗 编辑:提供示例数据 编辑:我的问题解决了,这只是在我的代码中构建范围查询时的一个拼写错误,我不认识它--但是这里的答案的解释可能会帮助其他人 一, 示例数据:
elasticsearch 弹性搜索查询行为,
elasticsearch,
elasticsearch-query,
elasticsearch,
elasticsearch Query,我对elasticsearch有两个不同的查询。这两个查询之间的区别在于,第一个查询在一个boolean-should查询中获得了两个搜索条件,第二个查询将其拆分为两个单独的bool-should查询。第一个返回预期的响应,但第二个与任何文档都不匹配,即使存在包含这两个条件的文档。如果我重构第二个,使两个拆分的bool-should查询被bool-should-query封装,它将返回预期的响应,就像查询1一样 问题是为什么查询2不像1和3那样返回响应?我错过什么了吗 编辑:提供示例数据 编辑:
{
"_index": "stof_64371064",
"_type": "_doc",
"_id": "1",
"_score": 0.0,
"_source": {
"streetNr": 90,
"geographicAddress": {
"city": "Berlin"
}
}
},
{
"_index": "stof_64371064",
"_type": "_doc",
"_id": "2",
"_score": 0.0,
"_source": {
"streetNr": 10,
"geographicAddress": {
"city": "Berlin"
}
}
}
在
应
和最小应匹配=1
中,您说如果其中一个条件正确,则返回您在查询1和查询3中设置的文档。但是在第二个查询中,您在filter
和elasticsearch搜索中设置了两个条件,并返回两个条件都有效的文档。因此,与其他查询中的应
相比,您的第二个查询表现为必须
。请参阅有关的ES官方文档,以详细了解各种条款。
第一个搜索查询的结构如下-
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{},
{}
],
"minimum_should_match": 1
}
}
]
}
}
}
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": {},
"minimum_should_match": "1"
}
},
{
"bool": {
"should": {},
"minimum_should_match": "1"
}
}
]
}
}
}
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"bool": {
"should": [
{}
],
"minimum_should_match": 1
}
},
{
"bool": {
"should": [
{}
],
"minimum_should_match": 1
}
}
],
"minimum_should_match": 1
}
}
]
}
}
}
filter
子句正在包装should
查询,但是在should
子句的末尾,添加了最小应匹配:1
,这表明1should
子句必须是强制性的
第二次搜索查询的结构如下-
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{},
{}
],
"minimum_should_match": 1
}
}
]
}
}
}
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": {},
"minimum_should_match": "1"
}
},
{
"bool": {
"should": {},
"minimum_should_match": "1"
}
}
]
}
}
}
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"bool": {
"should": [
{}
],
"minimum_should_match": 1
}
},
{
"bool": {
"should": [
{}
],
"minimum_should_match": 1
}
}
],
"minimum_should_match": 1
}
}
]
}
}
}
在这里,由于您在每个should
子句之后添加了“minimum\u should\u match”:“1”
,因此在某种程度上,它只起到了must
子句的作用,因为should
子句中只有一个条件需要匹配filter
子句应用于包含两个bool should
子句,因此当两个should
子句匹配时,只有您才能得到结果
第三个搜索查询的结构如下-
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{},
{}
],
"minimum_should_match": 1
}
}
]
}
}
}
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": {},
"minimum_should_match": "1"
}
},
{
"bool": {
"should": {},
"minimum_should_match": "1"
}
}
]
}
}
}
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"bool": {
"should": [
{}
],
"minimum_should_match": 1
}
},
{
"bool": {
"should": [
{}
],
"minimum_should_match": 1
}
}
],
"minimum_should_match": 1
}
}
]
}
}
}
在本文中,您使用了bool should
子句的多个组合。第一个外部bool should
子句,包装了另外两个bool should
子句。但是在您添加的最小值应匹配:1
的外部应子句末尾。因此,尽管这里有filter
子句,但它将返回一个结果,即使一个bool应该子句满足条件
添加带有索引数据、搜索查询和搜索结果的工作示例
索引数据:
{
"streetNr":0,
"geographicAddress":{
"city":"Berlin"
}
}
{
"streetNr":90,
"geographicAddress":{
"city":"Berlin"
}
}
"hits": [
{
"_index": "stof_64371064",
"_type": "_doc",
"_id": "1",
"_score": 0.0,
"_source": {
"streetNr": 90,
"geographicAddress": {
"city": "Berlin"
}
}
},
{
"_index": "stof_64371064",
"_type": "_doc",
"_id": "2",
"_score": 0.0,
"_source": {
"streetNr": 0,
"geographicAddress": {
"city": "Berlin"
}
}
}
]
搜索查询:(根据您的问题进行第二次搜索查询)
我不知道我是否理解正确,但即使查询2的行为像是必须的,它也应该返回文档,因为有两个匹配的文档?顺便说一句,我之所以选择查询3,是因为我在外部缺少了一个最小值应匹配=1。请问您是否可以共享一些示例索引数据,以便很容易重现您的问题?@Bhavya很抱歉我的回复太晚了,我只是刚刚开始阅读。在你的回答中,你反驳我的第二个问题的方式有点像我的第三个问题。(除了bool过滤器)您提供的示例数据对于我的案例来说非常好,但是我仍然不明白为什么我的第二个问题的形式没有返回该文档。你说这就像一个必须的条款,所以你的例子中的两个文档应该匹配,不是吗?请仔细阅读我下面的评论,如果你索引了我在回答中给出的相同样本数据,请让我知道你的问题是否得到解决@Niklas,并尝试你的搜索查询(你在问题中给出的),然后您将看到它返回唯一一个id为1的文档。这是因为,您添加了filter
子句,该子句包装了bool-should
子句。在每个bool should
子句中,您添加了minimum\u shoul\u match:1
参数。这意味着文档必须同时满足这两个条件(在每个bool should
子句中给出),那么只有它才会返回所需的文档。@Niklas second document(根据我的回答)不会随搜索查询一起返回,因为不满足范围的条件。然而,如果运行第一个和第三个搜索查询,则会发现它同时返回文档。这是因为在这两种情况下,should
子句的条件不是强制性的。@Niklas如果仔细观察,您会发现您的第三个搜索查询与我的第二个搜索查询有很大的不同。在第三个搜索查询中,您有4个bool-should
子句,而在我的第三个查询中,只有3个bool-should
子句。在我的第三个查询中,只有3个should子句,或者您的意思是过滤器在那里充当了一种should?但无论如何,这对我的问题并不重要。我没有看到在你的命中结果中,第二个结果得到streetNr 0,因此它不匹配,但在我的例子中,它得到了例如10,因此它应该同时匹配这两个结果,并且不会返回。你知道我的意思吗?我用样本数据编辑了我的问题,就像你用你的热门例子做的那样。谢谢你的努力和详细的解释,也许其他人会觉得这很有帮助。在我的例子中,我刚刚发现,在我构建范围查询的情况下,我的“geographicAddress”关键字中有一个拼写错误。查询的行为与预期的一样。