elasticsearch复合查询

r1wp621o  于 2021-06-15  发布在  ElasticSearch
关注(0)|答案(2)|浏览(331)

我使用下面的复合查询查询一个包含300条记录的弹性索引:

GET my_index/_search
{
  "size": 10,
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "should": [
              {
                "multi_match": {
                  "query": "card",
                  "fields": [
                    "title^1.0"
                  ]
                }
              }
            ],
            "must": {
              "term": {
                  "_index": {
                    "value": "my_index"
                  }
                }
            }
          }
        }
      ]
    }
  }
}

必须在索引上是因为这可能是一个多索引查询,这取决于某些业务逻辑(必须很可能是一个过滤器,我可以更改它,但这不是我的问题的一部分)。我得到同样的结果,以及过滤器)。
虽然我希望它返回与should子句匹配的文档,但我将返回索引(300)中的所有文档
为什么会这样?

jjjwad0x

jjjwad0x1#

添加索引数据和搜索查询的工作示例
索引数据:

{
    "title":"card",
    "cost":"55"
}
{
    "title":"Card making",
    "cost":"55"
}
{
    "title":"elasticsearch",
    "cost":"55"
}

搜索查询:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "filter": [
              {
                "term": {
                  "_index": {
                    "value": "index-name"
                  }
                }
              }
            ],
            "must": [
              {
                "multi_match": {
                  "fields": [
                    "title^1.0"
                  ],

                  "query": "card"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

搜索结果:

"hits": [
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.7549127,
        "_source": {
          "title": "card",
          "cost": "55"
        }
      },
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.55654144,
        "_source": {
          "title": "Card making",
          "cost": "55"
        }
      }
    ]
u5i3ibmn

u5i3ibmn2#

解决方法是在查询中添加minimumshouldmatch字段。结果查询将变为:

GET my_index/_search
{
  "size": 10,
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "multi_match": {
                  "query": "card",
                  "fields": [
                    "title^1.0"
                  ]
                }
              }
            ],
            "must": {
              "term": {
                  "_index": {
                    "value": "my_index"
                  }
                }
            }
          }
        }
      ]
    }
  }
}

我相信这背后的原因是bool查询被调优为提供最大数量的匹配结果(匹配越多越好)。因此,如果must/filter子句匹配,则甚至不执行should。通过添加“minimum\u should\u match”:1我们指示elasticsearch在返回文档之前至少匹配1个should子句。
elastic文档摘录:
bool查询采用了一种“匹配越多越好”的方法,因此每个匹配must或should子句的分数将被添加到一起,以提供每个文档的最终\u分数。
您可以使用minimum \u should \u match参数指定返回的文档必须匹配的should子句的数目或百分比。
如果bool查询至少包含一个should子句,并且没有must或filter子句,则默认值为1。否则,默认值为0。
有关其他有效值,请参阅minimum \u should \u match参数。
参考链接-https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html#bool-最小值应匹配

相关问题