Elasticsearch:为什么完全匹配的分数低于部分匹配

Elasticsearch: why exact match has lower score than partial match

我的问题

我搜索词form,但完全匹配的词form不是第一个结果。有什么办法可以解决这个问题吗?

我的搜索查询

{
  "query": {
    "match": {
      "word": "form"
    }
  }
}

结果

word             score
--------------------------
formulation      10.864353
formaldehyde     10.864353
formless         10.864353
formal   10.84412
formerly         10.84412
forma    10.84412
formation        10.574185
formula          10.574185
formulate        10.574185
format   10.574185
formally         10.574185
form     10.254687
former   10.254687
formidable       10.254687
formality        10.254687
formative        10.254687
ill-formed       10.054999
in form          10.035862
pro forma        9.492243

POST my_index/_analyze

搜索中的单词 form 只有一个标记 form

在索引中,form个标记为["f"、"fo"、"for"、"form"]; formulation 个标记为 ["f"、"fo"、...、"formulatio"、"formulation"]。

我的配置

过滤器

        "edgengram_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
        }

分析仪

      "analyzer": {
        "abc_vocab_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "keyword_repeat",
            "lowercase",
            "asciifolding",
            "edgengram_filter",
            "unique"
          ]
        },
        "abc_vocab_search_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "keyword_repeat",
            "lowercase",
            "asciifolding",
            "unique"
          ]
        }
      }

映射

        "word": {
          "type": "text",
          "analyzer": "abc_vocab_analyzer",
          "search_analyzer": "abc_vocab_search_analyzer"
        }

因为你这个字段的类型是text,也就是说ES会对该字段进行全文检索分析。而 ES 搜索过程是一种查找与您提供的单词最相似的结果。
要准确搜索单词 "form",请将搜索方法更改为 match_phrase
此外,您还可以阅读以下文章以了解有关不同 ES 搜索方法的更多信息: https://www.cnblogs.com/yjf512/p/4897294.html https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html

您以您看到的方式得到结果,因为您已经实施了 edge-ngram 过滤器并且 form 是与其相似的字词的子串。基本上在倒排索引中,它还会存储包含 formulationformal 等的文档 ID。

因此,您的相关性也会以这种方式计算。您可以参考 this link,我特别建议您阅读 Default SimilarityBM25 部分。虽然目前的默认相似度为 BM25,但 link 将帮助您了解评分的工作原理。

您需要创建另一个可以在 should 子句中应用的同级字段。您可以继续使用 Term Query 创建 keyword 子字段,但您需要注意区分大小写。

相反,如@Val 所述,您可以使用标准分析器创建 text 字段的兄弟。

映射:

   {
    "word":{
      "type": "text",
      "analyzer": "abc_vocab_analyzer",
      "search_analyzer": "abc_vocab_search_analyzer"
      "fields":{
        "standard":{
          "type": "text"
        }
      }
    }
  }

查询:

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "word": "form"
          }
        }
      ],
      "should": [                          <---- Note this
        {
          "match": {
            "word.standard": "form"
          }
        }
      ]
    }
  }
}

如果有帮助请告诉我!

看起来你的自定义分析器有问题,我创建了我的自定义 autocomplete 分析器,它使用 edge_ngramlowercase 过滤器,它对你的查询和 returns 我完全匹配在上面,这就是 Elasticsearch 的工作方式,完全匹配总是有更多的分数。,所以不需要显式创建另一个字段并提升它,默认情况下作为 Elasticsearch提高令牌匹配的精确匹配。

索引定义

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 10
        }
      },
      "analyzer": {
        "autocomplete": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete", 
        "search_analyzer": "standard" 
      }
    }
  }
}

索引几个文档

{
   "title" : "formless"
}

{
   "title" : "form"
}

{
   "title" : "formulation"
}

title 字段上搜索问题中提供的查询

{
  "query": {
    "match": {
      "title": "form"
    }
  }
}

完全匹配得分最高的搜索结果

"hits": [
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "1",
            "_score": 0.16410133,
            "_source": {
               "title": "form"
            }
         },
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "2",
            "_score": 0.16410133,
            "_source": {
               "title": "formulation"
            }
         },
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "3",
            "_score": 0.16410133,
            "_source": {
               "title": "formaldehyde"
            }
         },
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "4",
            "_score": 0.16410133,
            "_source": {
               "title": "formless"
            }
         }
      ]