Elasticsearch 中的同义词相关性问题
Posted
技术标签:
【中文标题】Elasticsearch 中的同义词相关性问题【英文标题】:Synonyms relevance issue in Elasticsearch 【发布时间】:2022-01-04 05:46:34 【问题描述】:我正在尝试在 elasticsearch 中配置同义词并完成示例配置。但是当我搜索数据时没有得到预期的相关性。 下面是索引映射配置:
PUT /test_index
"settings":
"index":
"analysis":
"filter":
"my_synonyms":
"type": "synonym",
"synonyms": [
"mind, brain",
"brainstorm,brain storm"
]
,
"analyzer":
"my_analyzer":
"tokenizer": "standard",
"filter": [
"lowercase"
]
,
"my_search_analyzer":
"tokenizer": "standard",
"filter": [
"lowercase",
"my_synonyms"
]
,
"mappings":
"properties":
"my_field":
"type": "text",
"analyzer": "my_analyzer"
以下是我索引的示例数据:
POST test_index/_bulk
"index" : "_id" : "1"
"my_field": "This is a brainstorm"
"index" : "_id" : "2"
"my_field": "A different brain storm"
"index" : "_id" : "3"
"my_field": "About brainstorming"
"index" : "_id" : "4"
"my_field": "I had a storm in my brain"
"index" : "_id" : "5"
"my_field": "I envisaged something like that"
以下是我正在尝试的查询:
GET test_index/_search
"query":
"match":
"my_field":
"query": "brainstorm",
"analyzer": "my_search_analyzer"
当前结果:
"hits" : [
"_index" : "test_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.8185701,
"_source" :
"my_field" : "A different brain storm"
,
"_index" : "test_index",
"_type" : "_doc",
"_id" : "4",
"_score" : 1.4100728,
"_source" :
"my_field" : "I had a storm in my brain"
,
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.90928507,
"_source" :
"my_field" : "This is a brainstorm"
]
我期望与顶部的查询匹配的文档和与同义词匹配的文档应该得到低分。 所以在这里我的期望是价值“这是一场头脑风暴”的文档应该出现在位置一。
您能建议我如何实现吗?
我也尝试过应用提升和权重,但没有成功。
提前致谢!!!
【问题讨论】:
【参考方案1】:Elasticsearch 会“替换”同义词的每个实例以及所有其他同义词,并且在索引和搜索中都这样做(除非您提供单独的 search_analyzer),因此您会丢失确切的标记。要保留此信息,请将 subfield 与标准分析器一起使用,然后使用 multi_match 查询来匹配同义词或精确值 + 提升精确字段。
【讨论】:
感谢您的回复。这将在索引时使用多匹配查询。我在 elasticfourm 上也提出了同样的问题,并且仅在查询时得到了解决方案,而没有在索引映射级别进行任何更改。 这是另一种方式,是的。【参考方案2】:我从 Elastic 论坛here 得到了答复。我已复制以下内容以供快速参考。
你好,
由于您将同义词索引到倒排索引中,因此在分析器完成操作后,头脑风暴和头脑风暴都是不同的标记。因此,查询时的 Elasticsearch 使用您的分析器从您的查询中为大脑、风暴和头脑风暴创建标记,并将多个标记与索引 2 和 4 匹配,您的索引 2 的单词较少,因此 tf/idf 在两者和索引号 1 之间得分更高只匹配头脑风暴。
您还可以通过此查看分析器对您的输入做了什么;
POST test_index/_analyze
"analyzer": "my_search_analyzer",
"text": "I had a storm in my brain"
我做了一些尝试,您应该将索引分析器更改为 my_analyzer;
PUT /test_index
"settings":
"index":
"analysis":
"filter":
"my_synonyms":
"type": "synonym",
"synonyms": [
"mind, brain",
"brainstorm,brain storm"
]
,
"analyzer":
"my_analyzer":
"tokenizer": "standard",
"filter": [
"lowercase"
]
,
"my_search_analyzer":
"tokenizer": "standard",
"filter": [
"lowercase",
"my_synonyms"
]
,
"mappings":
"properties":
"my_field":
"type": "text",
"analyzer": "my_analyzer"
然后你想提高你的精确匹配,但你也想从 my_search_analyzer 令牌中获得命中,所以我稍微改变了你的查询;
GET test_index/_search
"query":
"bool":
"should": [
"match":
"my_field":
"query": "brainstorm",
"analyzer": "my_search_analyzer"
,
"match_phrase":
"my_field":
"query": "brainstorm"
]
结果:
"took" : 3,
"timed_out" : false,
"_shards" :
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
,
"hits" :
"total" :
"value" : 3,
"relation" : "eq"
,
"max_score" : 2.3491273,
"hits" : [
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 2.3491273,
"_source" :
"my_field" : "This is a brainstorm"
,
"_index" : "test_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.8185701,
"_source" :
"my_field" : "A different brain storm"
]
【讨论】:
以上是关于Elasticsearch 中的同义词相关性问题的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:通过结合 Elasticsearch 词干分析器和同义词来提高搜索相关性
Elasticsearch:Elasticsearch SQL介绍及实例