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
是与其相似的字词的子串。基本上在倒排索引中,它还会存储包含 formulation
、formal
等的文档 ID。
因此,您的相关性也会以这种方式计算。您可以参考 this link,我特别建议您阅读 Default Similarity
和 BM25
部分。虽然目前的默认相似度为 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_ngram
和 lowercase
过滤器,它对你的查询和 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"
}
}
]
我的问题
我搜索词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
是与其相似的字词的子串。基本上在倒排索引中,它还会存储包含 formulation
、formal
等的文档 ID。
因此,您的相关性也会以这种方式计算。您可以参考 this link,我特别建议您阅读 Default Similarity
和 BM25
部分。虽然目前的默认相似度为 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_ngram
和 lowercase
过滤器,它对你的查询和 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"
}
}
]