Java项目使用Elasticsearch实现拼音搜索

74 阅读4分钟

前言

JDK的版本,Spring Boot的版本,Elasticsearch版本的兼容性是非常严格的,所以我这边选用docker的方式来部署Elasticsearch。而我的Spring Boot用的是2.3.5版本,这个版本兼容的Spring Data Elasticsearch是4.0.5,所以选用的Elasticsearch版本是7.9.3。

1.安装Docker

windows10的话,需要开启虚拟化功能,并且必须更新至版本号 19041(20H2)或更高版本。windows11的可以从安装wsl开始。

检查一下电脑是否开启虚拟化,一般是默认开启的。 打开任务管理器,点击性能选项卡,然后点击CPU,查看是否开启了虚拟化。

a77372307ca9f0fae79d60090c72e443.png

然后启用 Hyper-v 并启用虚拟机平台。

通过控制面板->程序和功能->启用或关闭Windows功能,勾选下面四项

  • Hyper-V
  • 容器
  • 适用于Linux的Windows子系统
  • 虚拟机平台

06f9f3c329dcdcd114a16b8937094a8d.png

使用管理员权限打开PowerShell,执行以下命令:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

重启电脑。

Windows11可以从这里开始

安装WSL

执行命令,或是通过链接下载

wsl --install

设置WSL2为默认版本:

wsl --set-default-version 2

可以通过以下命令来检查 WSL 版本和已安装的 Linux 发行版:

wsl --list --version

下载并双击运行安装 Docker Desktop for Windows

配置国内镜像:

{
  "registry-mirrors": [
    "https://docker.hpcloud.cloud",
    "https://docker.m.daocloud.io",
    "https://docker.unsee.tech",
    "https://docker.1panel.live",
    "http://mirrors.ustc.edu.cn",
    "https://docker.chenby.cn",
    "http://mirror.azure.cn",
    "https://dockerpull.org",
    "https://dockerhub.icu",
    "https://hub.rat.dev"
  ]
}

d47e92d2a7e21b7092766fbe9e15a2ce.png

2.部署Elasticsearch

docker run -d --name es7-9-3 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.9.3

执行完毕之后,访问http://localhost:9200/ 查看是否启动成功。

19b3c5754f6a943a8b4dc431da01dcdf.png

然后安装Elasticsearch可视化工具Kibana,命令如下:

docker run -d --name kibana7-9-3 --link es7-9-3:elasticsearch -p 5601:5601 -e "I18N_LOCALE=zh-CN" -e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" kibana:7.9.3

执行完毕之后,访问http://localhost:5601/ 查看是否启动成功。

接下来安装拼音分词插件,执行如下命令进入容器内部环境:

docker exec -it es7-9-3 /bin/bash

然后执行如下命令安装拼音分词插件:

./bin/elasticsearch-plugin install https://release.infinilabs.com/analysis-pinyin/stable/elasticsearch-analysis-pinyin-7.9.3.zip

以及中文分词插件:

./bin/elasticsearch-plugin install https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-7.9.3.zip

安装完毕之后可以通过如下命令查看插件是否安装成功:

ls plugins/analysis-pinyin/

ls plugins/analysis-ik/

6305e4c5c5a460c984dd2f834267d079.png

注意Elasticsearch,Kibana以及插件的版本号一定要一致

3.Spring Boot项目集成Elasticsearch

在Spring Boot项目中集成Elasticsearch,首先需要在pom.xml文件中添加依赖,同样的,这里的版本要和Elasticsearch的版本保持一致。这里我选用了Rest High Level Client的方式链接,因为Transport Client在Elasticsearch 7.0版本之后已经被废弃了。

<properties>
    <elasticsearch.version>7.9.3</elasticsearch.version>
</properties>

<dependencies>
    <!-- Spring Data Elasticsearch -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
    </dependency>

    <!-- Elasticsearch Rest High Level Client (必须与 ES Server 版本一致) -->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>${elasticsearch.version}</version>
    </dependency>
</dependencies>

然后再来配置Elasticearch的连接,创建一个名为ElasticsearchConfig的配置类:

@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {

    @Override
    public RestHighLevelClient elasticsearchClient() {
        RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
        return new RestHighLevelClient(builder);
    }
}

接下来就可以跟我们的业务需求来实现拼音搜索了。

先创建一个实体类,这边我使用的MallGoods商城订单的实体类,es相关的就用了Es的前缀,然后需要title字段可以拼音搜索。

@Document(indexName = "mall_goods")
public class EsMallGoods {

    /**
     * 商品ID
     */
    @Id
    private String id;

    @Field(type = FieldType.Text, analyzer = "pinyin_analyzer", searchAnalyzer = "ik_smart")
    private String title;
}

然后创建一个Repository,继承ElasticsearchRepository接口,实现一个查询方法:

public interface EsMallGoodsRepository extends ElasticsearchRepository<EsMallGoods, String> {

    // 根据商品名称搜索
    List<EsMallGoods> findByTitle(String title);

}

最后通过PUT请求,在Elasticearch中创建索引,这边直接使用了Postmman工具:

curl -X PUT "http://localhost:9200/mall_goods" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "analysis": {
      "analyzer": {
        "pinyin_analyzer": {
          "tokenizer": "ik_max_word",
          "filter": ["pinyin_filter"]
        }
      },
      "filter": {
        "pinyin_filter": {
          "type": "pinyin",
          "keep_original": true,
          "keep_first_letter": true,
          "keep_full_pinyin": true,
          "keep_none_chinese": true,
          "lowercase": true
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "pinyin_analyzer",  // 写入时使用拼音分词
        "search_analyzer": "ik_smart"   // 搜索时使用IK分词
      }
    }
  }
}'

至此,Elasticsearch的拼音搜索就配置完成了。现在可以通过EsMallGoodsRepository的findByTitle的方法测试拼音搜索功能了。

结束语

之前一直工作忙,想要学习一下Elasticsearch,但是一直没时间,这几天抽空研究一下。现在回头看,其实Elasticsearch的拼音搜索并不难,当然这也只是很初级的实现方法,但中途却是因为版本兼容性问题,或是其他安装配置的问题,浪费了不少时间。

在这里记录一下,希望能帮助到有同样需求的朋友。