使Sudachi同义词词典实现Elasticsearch搜索

前提

    • macOS 13.0(22A380)

 

    • Docker version 24.0.6, build ed223bc

 

    • Elasticsearch 7.17.10

 

    • elasticsearch-model (7.2.1)

 

    elasticsearch-sudachi 7.17.10

办法步骤

使用Docker运行Elasticsearch(Sudachi)

tokenizer使用Sudachi作为工具(由于有插件所以使用)。

 

基本流程是将README文件提炼为以下几点:

在开始任务之前,有一些需要确认的事项。
由于需要匹配插件和ES的版本,所以先确认插件的版本。
查看插件列表,本次使用的是7系的最新版本 elasticsearch-7.17.10-analysis-sudachi-3.1.0.zip。

首先,要准备相同版本的ES(使用Docker的ES操作步骤)。

docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.10

docker run --detach --name es7-sudachi --net elastic -p 127.0.0.1:9200:9200 -p 127.0.0.1:9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.17.10

接下来,安装插件。

docker exec -it [コンテナID] /bin/bash

> bin/elasticsearch-plugin install https://github.com/WorksApplications/elasticsearch-sudachi/releases/download/v3.1.0/elasticsearch-7.17.10-analysis-sudachi-3.1.0.zip

需要另外准备一本词典。
有几种类型的词典可供选择,本次将准备使用全面的词典(首先需要准备核心词典)。
每个词典都有对应的链接。

# Core辞書を入れるディレクトリを用意
> mkdir /usr/share/elasticsearch/config/sudachi

> cd /tmp/

# Core辞書
> curl -O http://sudachi.s3-website-ap-northeast-1.amazonaws.com/sudachidict/sudachi-dictionary-20230927-core.zip
> unzip sudachi-dictionary-20230927-core.zip
> cp sudachi-dictionary-20230927/system_core.dic /usr/share/elasticsearch/config/sudachi/

# Full辞書
> curl -O http://sudachi.s3-website-ap-northeast-1.amazonaws.com/sudachidict/sudachi-dictionary-20230927-full.zip
> unzip sudachi-dictionary-20230927-full.zip
> cp sudachi-dictionary-20230927/system_full.dic /usr/share/elasticsearch/plugins/analysis-sudachi/

当你最后重新启动时,你会暂时能够使用Sudachi进行Elasticsearch搜索。

docker restart

准备Sudachi同义词词典。

Sudachi 提供了同义词词典,但如果保持原始格式,不能在ES中使用。

使用以下内容将格式转换

 

将转换结果带入容器内

docker cp synonym.txt [コンテナID]:/usr/share/elasticsearch/data/

创建索引

假设您正在使用elasticsearch-model。

在该模型中添加以下设置,并执行create_index!

...
  settings index: { number_of_shards: 1 } do
    mappings dynamic: 'false' do
      indexes :value, type: 'text', analyzer: 'sudachi_analyzer'
    end
  end

  settings analysis: {
    "tokenizer": {
      "sudachi_tokenizer": {
        "type": "sudachi_tokenizer",
        "discard_punctuation": true,
        "resources_path": "/usr/share/elasticsearch/plugins/analysis-sudachi/",
        "additional_settings": "{\"systemDict\":\"system_full.dic\"}"
      }
    },
    "filter": {
      "sudachi_synonym": {
        "type": "synonym_graph",
        "lenient": true,
        "synonyms_path": "/usr/share/elasticsearch/data/synonym.txt"
      }
    },
    "analyzer": {
      "sudachi_analyzer": {
        "tokenizer": "sudachi_tokenizer",
        "type": "custom",
        "char_filter": [],
        "filter": [
          "sudachi_part_of_speech",
          "sudachi_ja_stop",
          "sudachi_baseform",
          "sudachi_synonym"
        ]
      }
    }
  }
...

作为要点,

    • Full辞書を利用するために、 resources_path、additional_settings を設定する

https://github.com/WorksApplications/elasticsearch-sudachi#configuration

同義語辞書内の単語を解析できなくて失敗した際にスルーするため、lenient を設定する

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-synonym-graph-tokenfilter.html#_solr_synonyms_2:~:text=to%20true).-,lenient,-(defaults%20to%20false

确认动作

使得可以从 Kibana 上查看

docker run --detach --name kib7-sudachi --net elastic -p 127.0.0.1:5601:5601 -e "ELASTICSEARCH_HOSTS=http://es-sudachi:9200" docker.elastic.co/kibana/kibana:7.17.6

请访问 http://127.0.0.1:5601/app/dev_tools#/console。

GET [index名]/_analyze
{
  "analyzer": "sudachi_analyzer",
  "text" : "アイスクリーム"
}

=>

{
  "tokens" : [
    {
      "token" : "アイスクリーム",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "SYNONYM",
      "position" : 0
    },
    {
      "token" : "ice cream",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "SYNONYM",
      "position" : 0
    },
    {
      "token" : "アイス",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "SYNONYM",
      "position" : 0
    },
    {
      "token" : "ICE",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "SYNONYM",
      "position" : 0
    }
  ]
}

哇,这个被分析成同义词了?

bannerAds