Elasticsearch 的同义词功能是一个重要的文本分析工具,特别是在全文搜索应用中。同义词机制使得用户能够建立一个同义词库,以处理一词多义、多词同义等情况,从而增强搜索的准确性和丰富性。
1、同义词在搜索引擎领域用途
同义词在搜索引擎领域的用途可概括如下:
- 增强搜索的准确性——当用户输入一个关键词时,可能与他们实际意图相关的文档使用了一个不同的关键词或短语。同义词允许搜索引擎理解和识别这些情况,返回更准确的结果。如:“遥遥领先”和“华为Meta60”同义词。
- 提高用户体验——用户可能不知道或者忘记了某个特定的术语,但通过使用同义词,他们仍然可以找到他们正在寻找的内容。
- 多语言或方言支持——对于支持多种语言或方言的应用,同义词可以帮助桥接词汇差异,如:data 和 数据同义。
- 行业特定术语——特定行业或领域可能有其专有的术语,同义词可以帮助搜索引擎理解这些术语和更通用的关键词之间的关系。比如:“锤子”在计算机领域和其他领域含义不同。
2、Elasticsearch 领域同义词应用场景
电商平台
顾客可能会使用不同的关键词搜索相同的产品。
例如,他们可能搜索“冰箱”或“冷藏库”。通过使用同义词,电商平台可以确保无论客户使用哪种术语,都能找到相关的产品。
例如:“画匠、画工、画师”三个是同义词,“番茄,西红柿”是同义词......
新闻或内容聚合网站
人们可能使用不同的关键词来描述或搜索同一事件或主题。例如,“COVID-19”、“冠状病毒”和“新型冠状病毒”都可能指向与疫情相关的文章。
某特定新闻场景下,中文和英文要做同义词处理,举例:科学 和 science 是同义词,数据 和 data 是同义词.....
医疗或科学研究
不同的研究者可能使用不同的术语描述相同的概念或技术。
通过使用同义词,研究数据库可以确保研究者找到所有相关的文献,而不仅仅是使用特定术语的文献。
企业搜索
员工可能不熟悉所有公司内部使用的术语或缩写。比如:WOC和广域网加速是相同的含义。
同义词可以帮助员工更容易地找到他们正在寻找的内部文档或资源。
3、早期版本 Elasticsearch 同义词使用概览
我拿 Elastic 认证考试的同义词的一个知识点解读一下。
3.1 Elasticsearch 同义词用途
自定义分词,有同义词的业务场景。用户期望搜索相同的同义词组(二个或者多个),评分结果一致。
3.2 应用举例
同义词过滤 核心demo
PUT test_004/_bulk {"index":{"_id":1}} {"title":"oa is very good"} {"index":{"_id":2}} {"title":"oA is very good"} {"index":{"_id":3}} {"title":"OA is very good"} {"index":{"_id":4}} {"title":"dingding is very good"} {"index":{"_id":5}} {"title":"dingding is ali software"} {"index":{"_id":6}} {"title":"0A is very good"} # return 2 POST test_004/_search { "query": { "match": { "title": "dingding" } } } POST test_004/_search { "query": { "match": { "title": "OA" } } } DELETE task2 # 同义词的设置最核心 PUT /task2 { "settings": { "index": { "analysis": { "analyzer": { "synonym": { "tokenizer": "whitespace", "filter": [ "synonym" ] } }, "filter": { "synonym": { "type": "synonym", "lenient": true, "synonyms": [ "oa, oA, Oa, OA, 0A, dingding" ] } } } } }, "mappings": { "properties": { "title":{ "type": "text", "analyzer": "synonym" } } } } POST _reindex { "source": { "index": "test_004" }, "dest": { "index": "task1" } } GET task2/_mapping POST task2/_analyze { "analyzer": "synonym", "text":"dingding is good software" }
3.3 具体同义词含义解读
最核心部分:
- 举例1:"synonyms" : ["foo, bar => baz"]
含义是:foo 和 bar的同义词都是 baz。
等价于:foo 与 baz一致,bar与 baz一致。
- 举例2:"synonyms": [ "oa, oA, Oa, OA, 0A, dingding" ] 含义:oa, oA, Oa, OA, 0A, dingding 互为同义词。
检索:dingding等价于:检索——oa,oA,Oa,OA,0A, dingding。
上述方式的弊端非常明显:同义词不支持更新,如果需要更新需要 reindex 才可以!
那么有没有支持更新的方案呢?Elasticsearch 8.10 版本迎来新的更新。
4、Elasticsearch 同义词最新方案——同义词API
我们讨论了同义词以及它们在提供优质搜索体验中的重要性。
使用同义词能:
- 找到使用与搜索查询相似词语的文档;
- 使特定领域的词汇更加用户友好,让用户用他们熟悉的词找到结果;
- 纠正常见的拼写错误或打字错误。
随着时间的推移,搜索结果需要不断演变。
新商品上架,新趋势改变了用户的搜索习惯,新词汇成为搜索领域的一部分。
为了应对这些变化,Elasticsearch引入了新的同义词API,以帮助无缝管理和更新同义词。
5、为何 Elasticsearch 需要同义词API?
在以前的做法中,更新同义词有些步骤需要手动操作:
- 我们需要将同义词文件上传到 Elasticsearch 集群的每个节点。
- 必须确保同义词过滤器(Token Filters)配置了正确的路径。
- 同义词文件需要在每个节点上进行更新,并保持同步。
这样做是可行的,但它涉及到像文件上传、维护更新等基础设施工作,并需要了解每个同义词文件的用途。
现在,8.10 版本之后,我们进入同义词API时代。
与之前基于文件的同义词更新方法相比,使用同义词API有多个优点:
- 提供了一个基于API的机制用于定义同义词。
- 对分析过程提供了自动重新加载机制,后面会用到 updateable 参数就是解决这个问题。
- 允许进行细粒度的同义词管理。
6、Elasticsearch 同义词 API 实操指南
6.1 创建同义词集
你可以用以下API请求创建一个新的同义词集:
PUT _synonyms/my-synonyms-set { "synonyms_set": [ { "id": "pc", "synonyms": "pc => personal computer" }, { "id": "computer", "synonyms": "computer,laptop" } ] }
6.2 配置同义词集
一旦创建,你的同义词集可以用作同义词、同义词集合(set)过滤器的一部分。配置如下:
PUT /synonym_set_test { "settings": { "index": { "analysis": { "analyzer": { "synonym_analyzer": { "tokenizer": "whitespace", "filter": ["my_synonyms"] } }, "filter": { "my_synonyms": { "type": "synonym", "synonyms_set": "my-synonyms-set", "updateable": true } } } } } }
6.3 更新同义词集
6.3.1 批量更新
你可以通过更新所有的同义词规则来更新一个同义词集。
PUT _synonyms/my-synonyms-set { "synonyms_set": [ { "id": "pc", "synonyms": "pc => personal computer" }, { "id": "computer", "synonyms": "computer, pc, laptop, desktop" } ] }
6.3.2 单个更新
或者,你也可以管理单个同义词规则:
PUT _synonyms/my-synonyms-set/computer { "synonyms": "computer, pc, laptop, desktop" }
6.4 验证一把同义词效果
## 设置同义词集合 PUT _synonyms/my-synonyms-set-v1 { "synonyms_set": [ { "id": "huawei", "synonyms": "huawei, yylx, yyds" } ] } ## 创建索引,自定义分词指定同义词集 PUT synonym_set_test_v1 { "settings": { "index": { "analysis": { "analyzer": { "synonym_analyzer": { "tokenizer": "whitespace", "filter": [ "my_synonyms" ] } }, "filter": { "my_synonyms": { "type": "synonym", "synonyms_set": "my-synonyms-set-v1", "updateable": true } } } } }, "mappings": { "properties": { "title": { "type": "text", "search_analyzer": "synonym_analyzer" } } } } ## 批量写入数据 POST synonym_set_test_v1/_bulk {"index":{"_id":1}} {"title":"yylx is very well"} {"index":{"_id":2}} {"title":"yyds is very good"} {"index":{"_id":3}} {"title":"huawei is very nb"}
注意:易出错点!
执行如下检索后,
## 执行检索 POST synonym_set_test_v1/_search { "query": { "match": { "title": "yyds" } } }
召回结果如下:
再执行一下同义词更新:
## 更新词典 PUT _synonyms/my-synonyms-set-v1 { "synonyms_set": [ { "id": "huawei", "synonyms": "huawei, yylx, yyds, meta60, 遥遥领先" } ] }
再执行一下如下检索:
## 依然可以召回!! POST synonym_set_test_v1/_search { "query": { "match": { "title": "遥遥领先" } } }
召回结果如下:
6.5 同义词API 使用小结及注意事项
当你在Elasticsearch中使用同义词时,关键的决策在于:是在索引时使用它们,还是在搜索时使用它们?
- 场景1:索引时使用
这意味着当你把文档输入到 Elasticsearch 时,同义词就已经被应用了。
这种方式的缺点是,如果你想更改同义词,就必须重新对所有数据进行索引,这既耗时又可能导致数据中断。
- 场景2:搜索时使用
这意味着只有当执行搜索时,同义词才会被应用。
这种方式更加灵活,因为你可以随时更改同义词,而无需重新索引。
特别是,如果你的令牌过滤器配置了"updateable": true,当你更改同义词时,可以重新加载搜索分析器。
还有一个小贴士:如果你使用Elasticsearch的同义词 API 创建的同义词集,那么它们只能在搜索时使用(对应上面介绍的报错截图理解一下这里)。
所以,你可以选择将包含同义词集的分析器指定为搜索时分析器,也可以指定为索引时分析器。但记住,选择哪种方式主要取决于你的业务需求和对数据灵活性的考虑。
7、同义词相关企业级实战问题清单
如下问题来自死磕Elasticsearch知识星球2018——2023年的真实企业级问题。
7.1 问题1:开源同义词库推荐
大家有做过同义词功能的吗,同义词都是手工添加的吗?有没有开源的,可以直接拿来用的,不用很复杂,就是我们平时理解的同义词就行?
回复:推荐还是自己构建吧,否则在查询的会出现很多莫名其妙的问题。
同义词开源库:
https://github.com/fighting41love/funNLP/blob/master/data/同义词库、反义词库、否定词库/同义词库.txt
7.2 问题2:关于历史数据不生效的问题?
大神,咨询个问题:es中加同义词和自定义分词之后,对于历史数据不生效的问题,如果处理?
分词:我确认必须reindex才生效,同义词我认为原理一样(我没有验证,但你可以试一下)
原理:数据再写入的时候会生成倒排索引,依据词典,词典更新发生在写入之前,所以不可以。
铭毅回复——一般操作:
- 1,尽量提前找全词;
- 2,更新词典发生在业务不忙的时候,比如凌晨;
- 3,更新词典,对新写入数据立即生效,对老数据,必须reindex操作,为保障线上业务正常访问,务必使用别名。
7.3 问题3:关于检索方案相关?
请问存储的是代码,但是搜索的时候代码及代码对应的中文都能搜索到数据是否能做到。
比如有个HY_DM字段存储的是行业代码:
如01 02 03,01对应第一产业,02、03类似,在搜索时搜索 “01”可以命中这个数据,在搜索“第一产业”时也能命中这个数据。
主要考虑的是如果同时存储代码和对应中文解释,占空间会比较大,我目前考虑同义词可能是一种方式,但是有错误命中的可能,比如在另一个代码中也是编码01,我搜索“第一产业”也命中了。
铭毅回复:同义词或者还可以考虑写入前数据建模,建模两个字段 两个字段做了一一对应关系。
现在看用 同义词 API 完全可以搞定。
8、小结
管理你的搜索体验中的同义词从未如此简单!与其使用文件并更新每个文件和相关的索引分析器,不如现在使用新的同义词API来定义同义词,并通过自动重新加载所需的分析器来更新它们。赶快试试看吧!
虽然同义词是一个非常强大的工具,但在实施时需要注意以下几点:
- 维护同义词库需要时间和努力。随着时间的推移,术语和用法可能会发生变化,同义词库需要定期更新。
- 过多的同义词可能导致搜索结果变得不准确。需要权衡准确性和搜索的广度。
总的来说,同义词是Elasticsearch中一个强大的特性,可以显著增强搜索的质量和用户体验,但需要谨慎维护和使用。
参考
- https://www.elastic.co/guide/en/elasticsearch/reference/8.10/put-synonyms-set.html
- https://t.zsxq.com/13QIUCLN4
- https://www.elastic.co/cn/blog/update-synonyms-elasticsearch-introducing-synonyms-api
- https://github.com/elastic/elasticsearch/pull/97962
推荐阅读 - 全网首发!从 0 到 1 Elasticsearch 8.X 通关视频
- 重磅 | 死磕 Elasticsearch 8.X 方法论认知清单
- 如何系统的学习 Elasticsearch ?
- 2023,做点事
更短时间更快习得更多干货!
中国50%+Elastic认证专家出自于此!
比同事抢先一步学习进阶干货!