Elasticsearch 同义词

1. 同义词的核心概念

同义词功能的核心目的是:让不同的词或短语在搜索时被视为等价

例如:

  • 当用户搜索 手机 时,结果也应该包含标有 移动电话 或 cellular phone 的文档。

  • 搜索 番茄 时,也能找到关于 西红柿 的内容。

  • 对于品牌和通用名:耐克 和 Nike

  • 对于缩写和全称:北大 和 北京大学UI 和 User Interface

2. 同义词的工作阶段:索引时 vs. 查询时

这是理解同义词最关键的一点。同义词可以在两个阶段应用,各有优劣。

特性索引时(Index Time)查询时(Search Time)
工作原理在文档索引(存入ES)时,同义词规则被应用到原始文本,扩展后的词项被直接存入倒排索引倒排索引中存储的是原始词项。在用户查询时,查询词会被同义词规则扩展,然后再去索引中匹配。
索引大小更大。因为原始词和所有同义词都被存入了索引。更小。索引中只存原始词。
查询性能更快。查询时无需做任何扩展处理,直接查询。稍慢。每次查询都需要进行同义词扩展,增加了一点开销。
灵活性。修改同义词规则后,必须重建索引(reindex)才能使新规则生效,非常麻烦。极好。修改同义词文件后,只需重启分词器或使用 _reload_search_analyzers API 即可生效,无需重建索引。
推荐场景数据一旦写入就不再变更,且同义词规则非常稳定的场景。现在一般不推荐使用绝大多数场景的推荐做法。数据频繁更新,同义词规则需要动态调整的场景。

3. 如何配置同义词

同义词功能是通过自定义分析器(Analyzer) 中的同义词分词过滤器(Synonym Token Filter) 来实现的。

步骤 1:定义同义词规则文件

创建一个纯文本文件(如 synonyms.txt),每行定义一条同义词规则。Elasticsearch 支持两种主要格式:

a) Solr 格式(显式映射)
使用 => 符号指定一组词的映射关系。

txt

# 将左侧的词映射为右侧的词(单向扩展)
手机, 移动电话 => 手机
西红柿 => 番茄
  • 索引时移动电话 会被替换为 手机 并存入索引。西红柿 会被替换为 番茄

  • 查询时:查询 移动电话 会被替换为查询 手机

b) WordNet 格式(分组等价)
使用逗号分隔一组等价同义词。

txt

# 这一行的所有词互为同义词,会双向扩展
手机, 移动电话, 蜂窝电话, cellphone
番茄, 西红柿
  • 索引时:任何一词都会被扩展为所有同义词(手机, 移动电话, 蜂窝电话, cellphone)存入索引。(如果索引时使用,会导致索引巨大)

  • 查询时:查询任何一词都会被扩展为查询所有同义词。

最佳实践:对于查询时同义词,强烈推荐使用 Solr 格式进行单向映射,以避免查询过度扩展引入噪声。例如,将不常见的词映射到最 common 的词上。

步骤 2:将同义词文件放入 ES 配置目录

将 synonyms.txt 文件放到 Elasticsearch 所有节点的 config 目录下(如 /etc/elasticsearch/synonyms.txt)。

步骤 3:创建自定义分析器

在索引的 settings 中配置一个使用同义词过滤器(synonym)的自定义分析器。

json

PUT /my_index
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_synonym_analyzer": { // 分析器名称
            "tokenizer": "ik_max_word", // 这里示例使用IK中文分词器
            "filter": [
              "my_synonym_filter" // 应用我们自定义的同义词过滤器
            ]
          }
        },
        "filter": {
          "my_synonym_filter": {
            "type": "synonym",
            "synonyms_path": "synonyms.txt", // 同义词文件路径
            "updateable": true // 关键!允许查询分析器动态重载同义词文件(ES 7.3+)
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word", // 索引时用的分词器
        "search_analyzer": "my_synonym_analyzer" // 查询时用的分词器(应用同义词)
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "my_synonym_analyzer"
      }
    }
  }
}

关键配置说明:

  • synonyms_path: 相对于 config 目录的路径。

  • updateable: 设置为 true 允许在不关闭索引的情况下,动态重载同义词文件(需要与 _reload_search_analyzers API 配合使用)。

  • 在 mappings 中,为需要的字段指定 search_analyzer 为我们自定义的包含同义词的分析器。而 analyzer(索引分析器)通常不使用同义词过滤器,以保持索引清洁。

4. 管理同义词(动态更新)

这是生产环境的关键。ES 7.3+ 提供了优雅的解决方案:

  1. 修改 config/synonyms.txt 文件。

  2. 使用以下 API 通知索引重新加载搜索分析器(即查询时分析器):

json

POST /my_index/_reload_search_analyzers

执行后,所有新的查询都会立即使用新的同义词规则,无需停机或重建索引。

5. 高级技巧与注意事项

  • 多词同义词(Synonyms with phrases)
    对于像 纽约 和 New York City 这样的多词同义词,处理起来比较复杂。需要确保分词器能正确地将它们作为一个整体处理。通常需要配合使用 flush_interval 和分词规则。

    txt

    纽约, "New York City"
  • 区分大小写:同义词匹配默认是区分大小写的。Apple(公司)和 apple(水果)可能是不同的。确保你的同义词规则和文本处理流程保持一致(通常先统一转为小写)。

  • 词干提取与同义词的顺序:如果你的分析链中同时有词干提取器(stemmer) 和同义词过滤器通常建议先做同义词,再做词干提取。例如,先通过同义词将 running 映射为 sprinting,然后再对 sprinting 进行词干提取得到 sprint

  • 测试你的分析器:使用 _analyze API 来测试你的配置是否正确。

    json

    GET /my_index/_analyze
    {
      "analyzer": "my_synonym_analyzer",
      "text": "我的移动电话"
    }

    检查输出结果是否包含你期望的同义词 手机

总结

方面建议
应用阶段首选查询时(Search Time),灵活性极高。
规则格式首选 Solr 格式(=>) 进行单向映射,更好控制。
文件管理将 synonyms.txt 置于 config 目录,并设置 "updateable": true
动态更新使用 _reload_search_analyzers API 动态加载更改。
测试务必使用 _analyze API 验证分析结果。

正确配置和使用同义词能极大提升搜索体验,使其更加智能和人性化。

### Elasticsearch 同义词插件配置与使用 #### 1. 同义词的功能概述 Elasticsearch同义词功能可以显著增强搜索体验,使用户能够在查询时匹配到具有相似意义的不同词语。这种能力对于电商网站、内容管理系统以及其他需要精准检索的应用场景尤为重要[^3]。 #### 2. 配置同义词的方式 Elasticsearch 支持多种方式来定义和应用同义词: - **静态同义词配置** 在 `settings` 和 `mappings` 文件中直接指定同义词列表。这种方式适合于固定不变的同义词集合。 - **动态同义词插件 (elasticsearch-dynamic-synonym)** 动态同义词插件允许在不重启服务的情况下实时更新同义词表,极大提高了系统的灵活性和可维护性[^1]。 #### 3. 安装动态同义词插件 为了实现动态管理同义词的能力,可以通过以下步骤安装并启用 `elasticsearch-dynamic-synonym` 插件: ##### 步骤一:确认 Java 环境已正确配置 由于 Elasticsearch 基于 Java 开发,因此在安装之前需确保系统已经安装了合适的 JDK 版本[^4]。 ##### 步骤二:下载并安装插件 假设当前使用的 Elasticsearch 版本为 6.8.13,则可通过如下命令完成插件安装: ```bash ./bin/elasticsearch-plugin install https://github.com/klawrrr/elasticsearch-dynamic-synonym/releases/download/v6.8.13/elasticsearch-dynamic-synonym-6.8.13.zip ``` > 注意:插件版本应严格匹配所使用的 Elasticsearch 主程序版本。 #### 4. 配置动态同义词 以下是基于动态同义词插件的一个典型配置示例: ```json PUT /my_index { "settings": { "analysis": { "filter": { "synonym_filter": { "type": "dynamic_synonym", "url": "/path/to/synonyms.txt" } }, "analyzer": { "synonym_analyzer": { "tokenizer": "standard", "filter": [ "lowercase", "synonym_filter" ] } } } }, "mappings": { "properties": { "title": { "type": "text", "analyzer": "synonym_analyzer" } } } } ``` 在此配置中,指定了一个外部文件 `/path/to/synonyms.txt` 来存储实际的同义词数据[^2]。 #### 5. 更新同义词 当需要修改现有的同义词集时,只需更改指向的 `.txt` 文件内容即可。例如,如果希望新增一组同义词关系 “phone, mobile”,则可以在文件中追加一行: ``` phone => mobile ``` 随后保存文件,插件会在后台自动检测变更并生效新规则[^1]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值