Elasticsearch查询行为

问题描述

我对我的elasticsearch有两个不同的查询。这两个查询间的区别在于,第一个查询一个布尔应查询中获得了两个搜索条件,第二个查询将其拆分为两个单个布尔应查询。第一个返回预期的响应,但是第二个与任何文档都不匹配,即使存在同时包含两个条件的文档。如果我重构第二个布尔值,以便两个拆分的布尔值(如果查询是由布尔值封装的,则布尔型应该是查询),它将返回预期的响应,就像查询1一样。

问题是为什么查询2不会像1和3那样返回响应?我想念什么吗?

编辑:提供示例数据

编辑:我的问题解决了,这只是在我的代码中构建范围查询时的一个拼写错误,但我无法识别-.-,但是这里答案的解释可能会对其他人有所帮助。

1。

GET _search
{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "range": {
                  "streetNr": {
                    "from": "1","to": "100","include_lower": true,"include_upper": true,"boost": 1
                  }
                }
              },{
                "match": {
                  "geographicAddress.city": {
                    "query": "Berlin"
                  }
                }
              }
            ],"minimum_should_match": "1"
          }
        }
      ]
    }
  }
}
GET _search
{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "range": {
                  "streetNr": {
                    "from": "1","boost": 1
                  }
                }
              }
            ],"minimum_should_match": "1"
          }
        },{
          "bool": {
            "should": [
              {
                "match": {
                  "geographicAddress.city": {
                    "query": "Berlin"
                  }
                }
              }
            ],"minimum_should_match": "1"
          }
        }
      ]
    }
  }
}
GET _search
{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "should": [
                    {
                      "range": {
                        "streetNr": {
                          "from": "1","boost": 1
                        }
                      }
                    }
                  ],"minimum_should_match": "1"
                }
              },{
                "bool": {
                  "should": [
                    {
                      "match": {
                        "geographicAddress.city": {
                          "query": "Berlin"
                        }
                      }
                    }
                  ],"minimum_should_match": "1"
                }
              }
            ],"minimum_should_match": "1"
          }
        }
      ]
    }
  }
}

示例数据:

      {
        "_index": "stof_64371064","_type": "_doc","_id": "1","_score": 0.0,"_source": {
          "streetNr": 90,"geographicAddress": {
            "city": "Berlin"
          }
        }
      },{
        "_index": "stof_64371064","_id": "2","_source": {
          "streetNr": 10,"geographicAddress": {
            "city": "Berlin"
          }
        }
      }

解决方法

请参阅bool query上的ES官方文档,以详细了解各个条款。

首次搜索查询的结构类似于-

 {
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {},{}
            ],"minimum_should_match": 1
          }
        }
      ]
    }
  }
}

filter子句包装了should查询,但是在should子句的末尾添加了"minimum_should_match": 1,这表明1 should子句必须是强制性的

您的第二次搜索查询的结构类似于-

{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": {},"minimum_should_match": "1"
          }
        },{
          "bool": {
            "should": {},"minimum_should_match": "1"
          }
        }
      ]
    }
  }
}

由于您在每个"minimum_should_match": "1"子句之后添加了should,所以从某种意义上说,它的作用仅像must子句,因为should子句中需要匹配的一个条件。 filter子句被同时包含两个bool should子句,因此,当两个should子句都匹配时,只有您将得到结果。

第三个搜索查询的结构类似于-

{
  "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子句。但是,在外部should子句的末尾,您已经添加了"minimum_should_match": 1。因此,尽管这里有filter子句,但是即使一个bool should子句满足条件,它也会返回结果。

添加包含索引数据,搜索查询和搜索结果的工作示例

索引数据:

{
  "streetNr":0,"geographicAddress":{
    "city":"Berlin"
  }
}
{
  "streetNr":90,"geographicAddress":{
    "city":"Berlin"
  }
}

搜索查询:(根据您的问题进行第二次搜索查询)

    {
  "query": {
    "bool": {
      "should": [          <-- note this
        {
          "bool": {
            "should": [
              {
                "range": {
                  "streetNr": {
                    "from": "1","to": "100","include_lower": true,"include_upper": true,"boost": 1
                  }
                }
              }
            ],{
          "bool": {
            "should": [
              {
                "match": {
                  "geographicAddress.city": {
                    "query": "Berlin"
                  }
                }
              }
            ],"minimum_should_match": "1"
          }
        }
      ]
    }
  }
}

搜索结果:

"hits": [
      {
        "_index": "stof_64371064","_type": "_doc","_id": "1","_score": 0.0,"_source": {
          "streetNr": 90,"geographicAddress": {
            "city": "Berlin"
          }
        }
      },{
        "_index": "stof_64371064","_id": "2","_source": {
          "streetNr": 0,"geographicAddress": {
            "city": "Berlin"
          }
        }
      }
    ]
,

shouldminimum should match=1中,您说如果其中一个条件正确,则返回在查询1和3中设置的文档。但是在第二个查询中,您在filter内设置了两个条件,并在Elasticsearch搜索中设置了两个条件都对它们有效的文档。因此,与其他查询中的must相比,第二个查询的行为类似should

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...