ElasticSearch 使用记录

ElasticSearch 使用记录

项目有全文搜索需求,MySQL 的 LIKE 查询太慢,上了 ElasticSearch。记录安装和接入过程,主要踩坑在权限问题和 ik 分词器版本匹配上。

ElasticSearch 是一个分布式、可扩展、实时的搜索与数据分析引擎,能从项目一开始就赋予数据搜索、分析和探索的能力,可用于全文搜索和实时数据统计。


安装

Linux(Docker)

  1. 修改虚拟内存区域大小,否则 ES 启动会失败:
sysctl -w vm.max_map_count=262144
  1. 启动容器(注意替换版本号):
docker run -p 9200:9200 -p 9300:9300 --name elasticsearch \
-e "discovery.type=single-node" \
-e "cluster.name=elasticsearch" \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-d elasticsearch:7.x.x
  1. 如果启动失败提示 data 目录没有访问权限:
chmod 777 /mydata/elasticsearch/data/
  1. 安装 IK 中文分词器(版本号需与 ES 一致):
docker exec -it elasticsearch /bin/bash
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.x.x/elasticsearch-analysis-ik-7.x.x.zip
docker restart elasticsearch
  1. 安装 Kibana(方便调试 DSL):
docker run --name kibana -p 5601:5601 \
--link elasticsearch:es \
-e "elasticsearch.hosts=http://es:9200" \
-d kibana:7.x.x # 版本号与 ES 保持一致

Spring Boot 接入(Spring Data Elasticsearch)

1. 添加依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2. 配置连接

spring:
data:
elasticsearch:
repositories:
enabled: true
cluster-nodes: 127.0.0.1:9300
cluster-name: elasticsearch

3. 定义文档实体

不需要中文分词的字段设置为 Keyword 类型,需要分词的设置为 Text 并指定分词器:

@Document(indexName = "product", type = "product")
@Data
public class EsProduct {
@Id
private Long id;

// 不分词,精确匹配
@Field(type = FieldType.Keyword)
private String productSn;

// 中文全文搜索,使用 ik_max_word 分词
@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String name;

@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String description;
}

常用注解说明:

注解说明
@Document映射到 ES 索引,indexName 对应索引名
@Id文档 ID
@Field(type=Keyword)不分词,适合精确匹配(商品编号、状态码等)
@Field(type=Text, analyzer="ik_max_word")中文分词,适合全文搜索

4. 自定义 Repository

public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> {

// 衍生查询:对 name、subTitle、keywords 三个字段全文搜索
Page<EsProduct> findByNameOrSubTitleOrKeywords(
String name, String subTitle, String keywords, Pageable page);
}

操作方式与 Spring Data MongoDB 类似,继承 ElasticsearchRepository 即可获得基本 CRUD 方法,也支持 @Query 注解编写 ES DSL 查询。