同义词热更新

更新时间:
复制为 MD 格式

云原生多模数据库 Lindorm搜索引擎支持用户上传并使用自己的同义词词典,并且可以热更新同义词词典,本文介绍如何使用自定义同义词,并热更新同义词的操作方式。

前提条件

定义同义词词典

番茄,西红柿
中心,中间,中央

每一行表示一组同义词,同义词之间用半角逗号 ',' 分隔,一行可以定义多个同义词,例如上述示例的第二行,定义“中心”,“中间”和“中央”三个词互为同义词。

上传同义词文件

  1. 登录Lindorm管理控制台

  2. 在页面左上角,选择实例所属的地域。

  3. 实例列表页,单击目标实例ID或者目标实例所在行操作列的管理

  4. 在左侧导航栏,选择搜索引擎

  5. 点击标签页词典热更新,点击更新词典文件进入页面。

  6. 将本地的同义词文件放在主词典框内,然后上传即可。

    说明
    • 保存同义词文件,文件前缀必须是 ld_synonyms_file_

    • 文件后缀名没有要求,示例中定义为 dic 仅为了表明该文件是个词典文件。

    • 在索引配置中引用词典文件的时候,需要的是去掉前缀部分的文件名。例如:上传的文件为ld_synonyms_file_my_synonyms.dic,则在索引 mapping 中指定的是my_synonyms.dic

创建索引时指定同义词文件

分词字段同义词支持通过analyzer(写入索引数据时使用)和search_analyzer(查询数据时使用)定义。

  • 在 analyzer 中配置同义词:同义词在写入时展开,更新同义词词典后需要重新构建索引才能生效。

  • 在 search_analyzer 中配置同义词:同义词在查询时展开,支持热更新,无需重建索引。

对于同义词热更新的场景,推荐使用 search_analyzer 的方式定义。

PUT /test
{
  "mappings" : {
      "properties" : {
        "content" : {
          "type" : "text",
          "analyzer": "ik_max_word", 
          "search_analyzer" : "my_synonym_analyzer"
        }
      }
  },
  "settings": {
    "index.number_of_shards":4,
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "synonyms_path": "my_synonyms.dic", 
          "updateable": true
        }
      },
      "analyzer": {
        "my_synonym_analyzer": {
          "type": "custom",
          "tokenizer": "ik_max_word",
          "filter": [
            "lowercase",
            "my_synonym_filter"
          ]
        }
      }
    }
  }
}

关键参数说明:

  • updateable:必须设置为 true,否则同义词热更新能力对该索引不适用。

  • synonyms_path:设置为文件名中 ld_synonyms_file_ 前缀后面的部分。

测试上传的同义词词典是否生效

在之前上传的同义词词典中定义了“番茄”和“西红柿”是一对同义词,查询“西红柿”可以搜索出“番茄”的结果。

# 写入一行数据
POST test/_doc?refresh
{
  "content": "小明爱吃番茄"
}

# 使用“番茄”的同义词查询
GET test/_search
{
  "query": {
    "match": {
      "content": "西红柿"
    }
  }
}

同义词热更新

当需要新增或修改同义词时,无需重建索引,只需更新词典文件并刷新分析器即可。

以下示例演示如何将"水果"添加为"番茄"和"西红柿"的同义词。先使用"水果"查询,此时查不出结果:

GET test/_search
{
  "query": {
    "match": {
      "content": "水果"
    }
  }
}

执行以下步骤完成同义词热更新:

  1. 更新本地的同义词词典文件,在“番茄,西红柿”后加上“水果”作为新的同义词,然后按照上传同义词文件的步骤重新上传更新后的词典文件。

番茄,西红柿,水果
中心,中间,中央
  1. 执行_refresh_search_analyzers API触发目标索引更新同义词。

POST _plugins/_refresh_search_analyzers/test
  1. 再次执行查询,此时可以查出数据,说明同义词热更新成功。

GET test/_search
{
  "query": {
    "match": {
      "content": "水果"
    }
  }
}

存量索引更新同义词词典的方式

如果此前已经创建好索引,且该索引之前没有定义同义词词典,可以通过以下步骤为存量索引配置同义词。

  1. 关闭索引

    警告

    该操作会导致索引暂停读写服务,建议在业务低峰期执行。

    POST test/_close
  2. 更新索引的settings,增加使用了同义词词典的analyzer定义。

    PUT /test/_settings
    {
      "analysis": {
        "filter": {
          "my_synonym_filter": {
            "type": "synonym",
            "synonyms_path": "my_synonyms.dic", 
            "updateable": true
          }
        },
        "analyzer": {
          "my_synonym_analyzer": {
            "type": "custom",
            "tokenizer": "ik_max_word",
            "filter": [
              "lowercase",
              "my_synonym_filter"
            ]
          }
        }
      }
    }
  3. 更新索引的 mappings,为需要引用同义词 analyzer 的字段增加 search_analyzer 定义。

    PUT test/_mapping
    {
      "properties" : {
        "content" : {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "my_synonym_analyzer"
        }
      }
    }
  4. 重新打开索引,执行查询验证同义词词典已生效。

    POST test/_open
    
    GET test/_search
    {
      "query": {
        "match": {
          "content": "西红柿"
        }
      }
    }