SpringBoot3.5.2+Elasticsearch8.15.2入门使用
·
1. Docker 部署 ES8(无密码版,适配自定义网络)
由于是学习测试,选择关闭 ES8 的安全认证和 SSL,直接用 HTTP 免密访问,同时挂载数据卷和插件卷,保证数据不丢失、可安装插件。
创建本地挂载目录
执行以下命令创建数据目录和插件目录,并设置权限为可读写:
mkdir -p /opt/es8/{data,plugins}
chmod 777 /opt/es8/data
chmod 777 /opt/es8/plugins
启动 ES8 容器
使用以下 Docker 命令启动 Elasticsearch 8 容器,关闭安全认证并配置 HTTP 访问:
docker run -d \
--name es8 \
--network hm-net \
--restart always \
-p 9200:9200 \
-p 9300:9300 \
-e discovery.type=single-node \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e xpack.security.enabled=false \
-e xpack.security.enrollment.enabled=false \
-e xpack.security.http.ssl.enabled=false \
-e xpack.security.transport.ssl.enabled=false \
-v /opt/es8/data:/usr/share/elasticsearch/data \
-v /opt/es8/plugins:/usr/share/elasticsearch/plugins \
elasticsearch:8.15.2
参数说明
--name es8:容器名称设置为es8。--network hm-net:容器连接到名为hm-net的网络。--restart always:容器自动重启策略设置为始终重启。-p 9200:9200:将主机的 9200 端口映射到容器的 9200 端口(HTTP API)。-p 9300:9300:将主机的 9300 端口映射到容器的 9300 端口(节点间通信)。-e discovery.type=single-node:配置为单节点模式。-e "ES_JAVA_OPTS=-Xms512m -Xmx512m":设置 JVM 堆内存为 512MB。-e xpack.security.enabled=false:关闭 X-Pack 安全功能。-v /opt/es8/data:/usr/share/elasticsearch/data:挂载数据目录到主机路径。-v /opt/es8/plugins:/usr/share/elasticsearch/plugins:挂载插件目录到主机路径。
将network的参数替换成自己的网络名即可
验证服务
运行以下命令检查容器是否启动成功:
docker ps -a | grep es8
访问 Elasticsearch HTTP API 确认服务正常运行:
curl http://localhost:9200
2. 安装IK中文分词器
IK分词器是Elasticsearch处理中文文本的必备插件。ES8默认不支持中文分词,因此必须手动安装IK分词器,并确保版本与ES8严格一致(如您使用的8.15.2)。以下是分步操作:
-
下载IK分词器:
- 访问IK分词器的官方GitHub仓库(https://github.com/medcl/elasticsearch-analysis-ik),下载与ES8版本匹配的IK分词器压缩包(例如,版本8.15.2)。
- 下载命令示例(在Linux终端执行):
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.15.2/elasticsearch-analysis-ik-8.15.2.zip
-
解压并放置到指定目录:
- 解压下载的文件,并将内容移动到ES8的插件目录。目录名必须为
ik(否则ES无法识别)。unzip elasticsearch-analysis-ik-8.15.2.zip -d /tmp/ik mkdir -p /opt/es8/plugins/ik cp -r /tmp/ik/* /opt/es8/plugins/ik/ - 注意:
/opt/es8/plugins/ik是ES容器的挂载目录(假设您已将ES数据卷映射到宿主机)。如果使用Docker,确保容器内路径一致。
- 解压下载的文件,并将内容移动到ES8的插件目录。目录名必须为
-
重启ES容器以加载插件:
- 重启ES8 Docker容器,使插件生效:
docker restart es8 - 检查日志确认加载成功:
docker logs es8 | grep ik # 应输出类似信息:"loaded plugin [analysis-ik]"
- 重启ES8 Docker容器,使插件生效:
-
验证分词效果:
- 使用Kibana的DevTools执行分词测试(如果Kibana已部署)。发送以下请求:
POST /_analyze { "analyzer": "ik_max_word", "text": "我喜欢用华为手机学习ES8" } - 成功响应应返回拆分后的中文词语数组(例如:["我", "喜欢", "用", "华为", "手机", "学习", "ES8"]),表明IK分词器安装生效。
- 使用Kibana的DevTools执行分词测试(如果Kibana已部署)。发送以下请求:
注意事项:
- 版本一致:IK分词器版本必须严格匹配ES8版本(如8.15.2),否则会导致ES启动失败。
- 目录权限:确保
/opt/es8/plugins/ik目录权限正确(建议chmod -R 755 /opt/es8/plugins/ik)。 - 容器环境:如果ES运行在Docker中,插件目录需映射到宿主机(例如,在
docker run命令中添加-v /opt/es8/plugins:/usr/share/elasticsearch/plugins)。
2. Kibana部署与基础操作
Kibana是ES的可视化管理工具,用于执行ES命令、查看数据。部署时必须与ES版本一致(如8.15.2),并连接到同一网络(如您使用的hm-net)。以下是部署步骤:
-
运行Kibana容器:
- 使用Docker命令启动Kibana,确保网络和版本匹配:
docker run -d \ --name kibana8 \ --network hm-net \ --restart always \ -p 5601:5601 \ -e "ELASTICSEARCH_HOSTS=http://es8:9200" \ kibana:8.15.2 - 参数说明:
--network hm-net:连接到与ES相同的Docker网络(ES容器名es8可通过网络名解析)。-e "ELASTICSEARCH_HOSTS=http://es8:9200":设置ES连接地址(es8是ES容器名,也可替换为自己的虚拟机地址,端口9200)。--restart always:确保容器自动重启。
- 使用Docker命令启动Kibana,确保网络和版本匹配:
-
访问Kibana并初始化:
- 在浏览器中访问Kibana:
http://<您的Linux服务器IP>:5601。 - 初始化需1-2分钟(首次访问时,Kibana会加载核心插件)。完成后,您将看到登录界面。
- 无需账号密码:由于ES8默认无安全配置,Kibana直接连接(无需认证)。
- 在浏览器中访问Kibana:
-
基础操作验证:
- 登录Kibana后,使用DevTools执行ES命令(例如,重复IK分词测试):
- 导航到 Management > Dev Tools。
- 输入并运行之前的JSON请求:
POST /_analyze { "analyzer": "ik_max_word", "text": "我喜欢用华为手机学习ES8" } - 成功返回分词结果,表示Kibana与ES连接正常。
- 登录Kibana后,使用DevTools执行ES命令(例如,重复IK分词测试):
注意事项:
- 网络配置:ES和Kibana必须在同一Docker网络(如
hm-net),否则连接失败(检查网络:docker network inspect hm-net)。 - 版本匹配:Kibana镜像版本(如
kibana:8.15.2)必须与ES版本完全相同。 - 初始化延迟:首次访问Kibana时,如果长时间无响应,检查容器日志:
docker logs kibana8(常见错误:网络不通或ES未运行)。 - 安全建议:生产环境建议启用ES安全特性(如设置密码),但根据您的描述,当前配置为简单开发环境。
总结
- IK分词器安装:确保版本一致、目录正确,重启ES后验证分词。
- Kibana部署:使用匹配版本的Docker命令,设置网络和ES连接地址,访问5601端口初始化。
Kibana 核心操作
创建索引库并配置 IK 分词
PUT /goods_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"category": {"type": "keyword"},
"price": {"type": "double"},
"stock": {"type": "integer"},
"brand": {"type": "keyword"}
}
}
}
批量插入测试数据
POST /goods_index/_bulk
{"index":{"_id":1}}
{"title":"华为Mate60手机","category":"手机数码","price":4999.00,"stock":200,"brand":"华为"}
{"index":{"_id":2}}
{"title":"小米14旗舰手机","category":"手机数码","price":3999.00,"stock":150,"brand":"小米"}
{"index":{"_id":3}}
{"title":"海尔变频冰箱","category":"大家电","price":2999.00,"stock":60,"brand":"海尔"}
高亮查询
GET /goods_index/_search
{
"query": {
"match": {
"title": "手机"
}
},
"highlight": {
"fields": {
"title": {}
},
"pre_tags": ["<span style='color:red'>"],
"post_tags": ["</span>"]
}
}
SpringBoot 整合 ES8
核心配置
spring:
elasticsearch:
uris: http://你的LinuxIP:9200 # 替换成自己的Linux服务器IP
socket-timeout: 60s
connect-timeout: 10s
实体类
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@Document(indexName = "goods_index") // 绑定ES索引库
public class Goods {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String title;
@Field(type = FieldType.Keyword)
private String category;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Integer)
private Integer stock;
@Field(type = FieldType.Keyword)
private String brand;
}
Repository 接口
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface GoodsRepository extends ElasticsearchRepository<Goods, Long> {
}
单元测试示例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class GoodsRepositoryTest {
@Autowired
private GoodsRepository goodsRepository;
@Test
public void testSave() {
Goods goods = new Goods();
goods.setId(4L);
goods.setTitle("苹果iPhone15");
goods.setCategory("手机数码");
goods.setPrice(5999.00);
goods.setStock(100);
goods.setBrand("苹果");
goodsRepository.save(goods);
}
@Test
public void testFindByTitle() {
goodsRepository.findByTitle("手机").forEach(System.out::println);
}
@Test
public void testDelete() {
goodsRepository.deleteById(4L);
}
}
增删改查操作
保存数据
Goods goods = new Goods();
goods.setId(5L);
goods.setTitle("联想拯救者笔记本");
goods.setCategory("电脑办公");
goods.setPrice(6999.00);
goods.setStock(50);
goods.setBrand("联想");
goodsRepository.save(goods);
查询数据
Optional<Goods> optionalGoods = goodsRepository.findById(5L);
if (optionalGoods.isPresent()) {
Goods goods = optionalGoods.get();
System.out.println(goods);
}
更新数据
Optional<Goods> optionalGoods = goodsRepository.findById(5L);
if (optionalGoods.isPresent()) {
Goods goods = optionalGoods.get();
goods.setPrice(6499.00);
goodsRepository.save(goods);
}
删除数据
goodsRepository.deleteById(5L);
官方Elasticsearch Java Client高亮查询示例解析
以下代码展示了使用Elasticsearch官方Java Client实现高亮查询的标准方式,核心要点如下:
@Test
void testAggregation2() throws IOException {
SearchResponse<Goods> search = esClient.search(s -> s
.index("hm-net")
.query(q -> q.match(m -> m.field("title").query("手机")))
.size(20)
.highlight(h -> h
.fields("title", f -> f
.preTags("<b>") // HTML高亮前缀标签
.postTags("</b>") // HTML高亮后缀标签
)
),
Goods.class);
// 处理高亮结果
search.hits().hits().forEach(hit ->
System.out.println(hit.highlight().get("title"))
);
}
关键组件说明
依赖注入
@Autowired
private ElasticsearchClient esClient;
使用Spring框架的依赖注入获取官方ElasticsearchClient实例
高亮配置结构
.highlight(h -> h
.fields("title", f -> f
.preTags("<b>")
.postTags("</b>")
)
)
通过链式调用定义高亮字段和HTML标记
结果处理
hit.highlight().get("title")
从返回结果中提取经过高亮处理的字段内容
注意事项
- 该方法需要
co.elastic.clients:elasticsearch-java依赖 - 返回的高亮内容是原始字段值加上HTML标签的版本
- 确保索引
hm-net包含title字段且为text类型 - 高亮标签
<b>可根据需求替换为其他HTML标签或CSS class
更多推荐
所有评论(0)