Elasticsearch DSL 过滤器

Elasticsearch DSL Filter

我在使用弹性搜索过滤器时遇到问题。我正在尝试使用弹性搜索 DSL 过滤器搜索文本,但我遇到了排序问题。

搜索文字:你好世界

文档中的其他字符串:Hello there, hello world, hello everyone, hi hello, etc...

Elasticsearch-dsl 查询是:

MyDocument.search().filter(Q("match", title="hello world") | Q("match", original_title="hello world")).execute()

Elasticsearch 查询是这样的:

{
    'bool': {
        'filter': [{
            'bool': {
                'should': [{
                    'match': {
                        'title': 'hello world'
                    }
                }, {
                    'match': {
                        'original_title': 'hello world'
                    }
                }]
            }
        }]
    }
}

输出类似于hello everyone, hi hello, hello world,等等

但我首先要 hello world

提前致谢!

在您的查询中,您使用的是 "filter"

The filter parameter indicates filter context. Its match clauses are used in filter context. They will filter out documents which do not match, but they will not affect the score for matching documents

如果您检查返回的匹配中的 _score,它将为零

将您的查询替换为

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "hello world"
          }
        },
        {
          "match": {
            "original_title": "hello world"
          }
        }
      ]
    }
  }
}

"hello world" 会比 "hello everyone, hi hello, hello world" 得到更高的分数 在弹性搜索中,较短的字段比较长的字段获得更高的分数。

根据您的查询,您似乎希望从多个字段中搜索相同的 token/tokens。

当然 @jaspreet 提到了你想要的答案,但是如果你想简化你的查询(当然 Bool Queries are also quite simple), then you can make use of query_string 如下:

POST <your_index_name>/_search
{
  "query": {
    "query_string": {
      "fields": ["title", "original_title"], 
      "query": "hello world",
      "default_operator": "OR"
    }
  }
}

您还可以使用 multi-match 查询来简化您的查询,如下所示:

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "hello world",
            "fields": ["title", "original_title"],
            "operator": "OR"
          }
        }
      ]
    }
  }
}

在这两种用例中,您都会得到想要的结果。

当然,您需要对其进行测试,看看响应如何出现以及使用这些可以解决哪些用例。

注意: 只是基于@Val 评论的附加说明,如果输入是什么,您也可以使用 simple query string 而不是 query_string来自用户,与 query_string 不同,它不会因语法无效而引发任何错误。

希望对您有所帮助!