Elasticsearch实现拼音搜索

475 阅读2分钟

绝大部分的搜索系统都是支持拼音搜索的,Elasticsearch实现拼音搜索需要安装elasticsearch-analysis-pinyin插件。
下面以7.17.0版本来演示如何实现拼音搜索

一. 安装

  1. 进到Elasticsearch的bin目录,执行指令:
    elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.17.0/elasticsearch-analysis-pinyin-7.17.0.zip

image.png

  1. 执行指令elasticsearch-plugin list,查看是否安装成功 image.png 图中analysis-pinyin显示安装成功
  2. 重启Elasticsearch
    如果是docker 安装的Elasticsearch,可执行指令docker restart elasticsearch

二、配置index

PUT /test-pinyin
{
    "settings": {
        "analysis": {
            "analyzer": {
                "ik_pinyin_analyzer": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "pinyin_filter"
                    ]
                }
            },
            "filter": {
                "pinyin_filter": {
                    "type": "pinyin",
                    "first_letter": "prefix",
                    "padding_char": " "
                }
            }
        }
    },
    "mappings": {
        "dynamic": "strict",
        "properties": {
            "content": {
                "type": "text",
                "fields": {
                    "pinyin": {
                        "type": "text",
                        "term_vector": "with_offsets",
                        "analyzer": "ik_pinyin_analyzer"
                    },
                    "standard": {
                        "type": "keyword" 
                    }
                }
            }
        }
    }
}

Settings 部分解释

analyzer
	ik_pinyin_analyzer:
            type: "custom":定义了一个自定义分析器。
            tokenizer: "standard":使用标准分词器对文本进行分词。
	filter:
            "lowercase":应用小写过滤器,将所有文本转换为小写。
            "pinyin_filter":应用自定义的拼音过滤器。
filter
	pinyin_filter:
            type: "pinyin":定义一个拼音过滤器,用于将汉字转换为拼音。
            first_letter: "prefix":拼音的第一个字母作为前缀。
            padding_char: " ":用空格填充拼音的字符,以便于索引和查询。

Mappings 部分解释

mappings.dynamic
	dynamic: "strict":
            设置为 strict 时,任何不在映射中定义的字段都不会被自动添加到映射中。这意味着如果你尝试插入一个未在映射中定义的字段,Elasticsearch 会拒绝这个文档。
mappings.properties
	content:
            type: "text":主字段,类型为 text,用于全文检索。
            fields:为 content 字段定义了多个子字段:
	pinyin:
            type: "text":子字段的类型为 text,用于支持拼音分析。
            term_vector: "with_offsets":存储词项向量和偏移量信息,用于做高亮显示等。
            analyzer: "ik_pinyin_analyzer":使用自定义的拼音分析器对该字段进行分析。
	standard:
            type: "keyword":子字段的类型为 keyword,用于精确匹配和聚合操作。

三、验证

  1. 插入数据
POST /test-pinyin/_bulk
{ "index": {} }
{  "content": "I love 中国"}
{ "index": {} }
{  "content": "I 中国万岁"}
{ "index": {} }
{  "content": "中华人民共和国万岁"}
  1. 搜索
POST /test-pinyin/_search
{
   "query":{
       "bool":{
           "should":[
               {
                   "match":{
                       "content.pinyin":"zhong guo"
                   }
               }
           ]
       }
   }
}

注意,这里是用子字段pinyin来搜索的,对应创建索引时,给子字段配置的分析器为ik_pinyin_analyzer

image.png