1. 项目结构
2. Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.13.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.22</version>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
3. application.yml
spring:
application:
name: spring_es
datasource:
url: jdbc:mysql://localhost:3306/es?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
4. 数据库执行语句(MYSQL)
-- 创建数据库
create database es;
-- 使用数据库
use es;
-- 创建数据库表
CREATE TABLE `blog`
(
`id` INT AUTO_INCREMENT PRIMARY KEY,
`title` VARCHAR(255) NOT NULL,
`content` TEXT NOT NULL,
`author` VARCHAR(100) NOT NULL,
`published_date` DATE NOT NULL
);
-- 插入20数据
INSERT INTO `blog` (`title`, `content`, `author`, `published_date`)
VALUES ('探索区块链的实际应用', '区块链技术不仅限于数字货币,其在供应链管理中的应用同样革命性。', '张三', '2022-07-15'),
('家庭园艺的基础知识', '简单介绍如何在家里开始你的园艺活动,包括基本的园艺工具和技巧。', '李四', '2022-06-20'),
('智能家居技术的前景', '随着科技的进步,智能家居逐渐走进我们的生活,带来了便利和安全。', '王五', '2022-08-01'),
('最新科技趋势大揭秘', '2023年科技行业的五大趋势,包括AI的进步和物联网的发展。', '赵六', '2022-05-11'),
('健康饮食的误区', '讨论常见的健康饮食误区,帮助你制定更科学的饮食计划。', '钱七', '2022-04-22'),
('如何选择跑鞋', '正确的跑鞋可以提升你的跑步体验,减少受伤的风险,了解如何选择适合你的跑鞋。', '孙八',
'2022-07-08'),
('提升时间管理能力', '高效的时间管理技巧可以让你事半功倍,这里有一些实用的建议。', '周九', '2022-03-30'),
('深入理解云计算', '云计算如何改变企业 IT 架构和成本效益,以及如何选择合适的云服务提供商。', '吴十', '2022-08-15'),
('精致咖啡的冲泡技巧', '从咖啡豆的选择到冲泡方法,一步步教你制作精致的咖啡。', '郑十一', '2022-07-18'),
('职场软技能的重要性', '软技能对职业发展同样重要,了解哪些软技能是你职业生涯的加分项。', '王十二', '2022-06-06'),
('程序员的学习路径', '如何成为一名成功的程序员?这里有一些关于学习路径和资源的建议。', '李十三', '2022-05-20'),
('数据分析的基本工具', '初学者如何入门数据分析,这些工具和技巧你不能错过。', '张十四', '2022-04-07'),
('运动对心理健康的好处', '运动不仅可以改善你的身体健康,还能提升你的心理状态。', '赵十五', '2022-03-15'),
('数字营销的最佳实践', '掌握数字营销的关键技巧,让你的业务在竞争激烈的市场中脱颖而出。', '周十六', '2022-08-10'),
('城市园林的设计原则', '城市园林设计不仅要美观,还应考虑生态和可持续性。', '吴十七', '2022-09-09'),
('远程工作的生产力技巧', '远程工作成为常态,如何保持高效?这些技巧可以帮到你。', '钱十八', '2022-02-28'),
('宠物照护的基本常识', '拥有宠物之前,了解这些基本的照护知识是必须的。', '孙十九', '2022-01-10'),
('探索古代中国的建筑艺术', '中国古代建筑不仅雄伟,每一砖一瓦都蕴含深厚的文化意义。', '周二十', '2022-10-01'),
('电影摄影的艺术技巧', '电影摄影不同于普通摄影,了解其背后的艺术和技术。', '赵二十一', '2022-11-11'),
('创新教育方法的探索', '传统教育方法已不适应新时代,探索更有效的教育创新方法。', '王二十二', '2022-12-12');
5. Blog.java
package org.example.pojo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
private String title;
private String content;
private String author;
private String publishedDate;
}
6. BlogMapper.java
package org.example.mapper;
import org.example.pojo.Blog;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface BlogMapper {
@Select("SELECT * FROM blog")
List<Blog> findAll();
}
7. SpringEsApplication.java
package org.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("org.example.mapper")
public class SpringEsApplication {
public static void main(String[] args) {
SpringApplication.run(SpringEsApplication.class, args);
}
}
8. SpringEsApplicationTests.java
package org.example;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.Refresh;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.example.mapper.BlogMapper;
import org.example.pojo.Blog;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.List;
@SpringBootTest
class SpringEsApplicationTests {
@Autowired
private BlogMapper blogMapper;
private RestClient restClient;
private ElasticsearchClient client;
@BeforeEach
void setUp(){
// 构建针对三个节点的低级 REST 客户端
restClient = RestClient.builder(
new HttpHost("192.168.163.128", 9201),
new HttpHost("192.168.163.129", 9202),
new HttpHost("192.168.163.130", 9203)
).build();
ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
client = new ElasticsearchClient(transport);
}
@AfterEach
void tearDown() throws IOException {
// 清理资源,关闭客户端
restClient.close();
}
@Test
void addIndex() throws IOException {
// 创建索引并指定 IK 分词器
CreateIndexResponse createIndexResponse = client.indices().create(c -> c
.index("blog")
.mappings(m -> m
.properties("title", p -> p.text(t -> t.analyzer("ik_max_word")))
.properties("content", p -> p.text(t -> t.analyzer("ik_max_word")))
.properties("author", p -> p.keyword(k -> k))
.properties("publishedDate", p -> p.date(d -> d))
)
);
System.out.println("索引创建并配置 IK 分词器确认: " + createIndexResponse.acknowledged());
}
@Test
void addDocumentsFromDatabase() throws IOException {
// 从数据库中获取所有博客数据
List<Blog> blogs = blogMapper.findAll();
for (Blog blog : blogs) {
// 添加文档到 Elasticsearch 索引
IndexResponse indexResponse = client.index(i -> i
.index("blog")
.document(blog)
.refresh(Refresh.True)
);
System.out.println("文档已索引1: " + indexResponse.result());
}
}
@Test
void searchDocuments() throws IOException {
// 执行搜索查询
SearchResponse<Blog> searchResponse = client.search(s -> s
.index("blog")
.query(q -> q
.match(m -> m
.field("content")
.query("技术")
)
), Blog.class);
System.out.println("搜索命中次数: " + searchResponse.hits().total().value());
searchResponse.hits().hits().forEach(hit -> System.out.println("文档标题: " + hit.source().getTitle()));
}
}
9. Kibana查看数据
#控制台DSL
POST /blog/_search
{
"query": {
"match": {
"content": "技术"
}
}
}
运行结果
{
"took": 35,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 2.3341897,
"hits": [
{
"_index": "blog",
"_id": "XWUYvpABaF6JgouTcLIi",
"_score": 2.3341897,
"_source": {
"title": "电影摄影的艺术技巧",
"content": "电影摄影不同于普通摄影,了解其背后的艺术和技术。",
"author": "赵二十一"
}
},
{
"_index": "blog",
"_id": "V2UYvpABaF6JgouTTrLn",
"_score": 1.943394,
"_source": {
"title": "探索区块链的实际应用",
"content": "区块链技术不仅限于数字货币,其在供应链管理中的应用同样革命性。",
"author": "张三"
}
}
]
}
}
10. 测试运行结果
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v3.3.1)
2024-07-17T08:53:02.740+08:00 INFO 18884 --- [spring_es] [ main] org.example.SpringEsApplicationTests : Starting SpringEsApplicationTests using Java 22.0.1 with PID 18884 (started by i in E:\ideaProject\spring_es)
2024-07-17T08:53:02.745+08:00 INFO 18884 --- [spring_es] [ main] org.example.SpringEsApplicationTests : No active profile set, falling back to 1 default profile: "default"
2024-07-17T08:53:13.164+08:00 INFO 18884 --- [spring_es] [ main] org.example.SpringEsApplicationTests : Started SpringEsApplicationTests in 13.065 seconds (process running for 18.899)
WARNING: A Java agent has been loaded dynamically (D:\apache-maven\apache-maven-3.9.6\repository\net\bytebuddy\byte-buddy-agent\1.14.17\byte-buddy-agent-1.14.17.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
搜索命中次数: 2
文档标题: 电影摄影的艺术技巧
文档标题: 探索区块链的实际应用
参考文献:
Installation | Elasticsearch Java API Client [8.13] | Elastic
Migrating from the High Level Rest Client | Elasticsearch Java API Client [8.13] | Elastic