Spring Boot 使用 ElasticSearch

第一步,开启本地的 ElasticSearch

启动 elasticSearch.bat

npm run start (head 插件)

第二步,在 Spring Boot 项目中引入依赖

复制代码
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.6.1</version>
        </dependency>

第三步,配置 yml 和 配置类

复制代码
# ES
elasticsearch:
  host: 127.0.0.1
  port: 9200
  username:  # 若 ES 无账号密码,可不填
  password:  # 若 ES 无账号密码,可不填
  connectTimeout: 5000   # 连接超时(毫秒)
  socketTimeout: 30000   # 读写超时(毫秒)
  maxConnTotal: 100      # 最大连接数
  maxConnPerRoute: 10    # 单路由最大连接数
java 复制代码
package com.wf.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticsearchConfig {

    @Value("${elasticsearch.host}")
    private String host;

    @Value("${elasticsearch.port}")
    private int port;

    @Value("${elasticsearch.username}")
    private String username;

    @Value("${elasticsearch.password}")
    private String password;

    @Value("${elasticsearch.connectTimeout}")
    private int connectTimeout;

    @Value("${elasticsearch.socketTimeout}")
    private int socketTimeout;

    @Value("${elasticsearch.maxConnTotal}")
    private int maxConnTotal;

    @Value("${elasticsearch.maxConnPerRoute}")
    private int maxConnPerRoute;

    @Bean
    public RestHighLevelClient restHighLevelClient() {

        // 构建 RestClient
        RestClientBuilder builder = RestClient.builder(
            new HttpHost(host, port, "http")
        )
        .setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(connectTimeout);
            requestConfigBuilder.setSocketTimeout(socketTimeout);
            return requestConfigBuilder;
        })
        .setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.setMaxConnTotal(maxConnTotal);
            httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
            return httpClientBuilder;
        });

        return new RestHighLevelClient(builder);
    }
}

第四步,实现实体类

java 复制代码
package com.wf.dao.ESPojo;

import lombok.Data;

@Data
public class ESArticle {
    private String id;          // ES 文档 ID
    private String title;       // 标题(测试 IK 分词)
    private String content;     // 内容(测试 IK 分词)
    private Long createTime;    // 在 ES 中的时间

    private String summary;//概述
    private Integer viewCounts;//浏览次数
    private String author;//作者
}

第五步,实现 Service

java 复制代码
package com.wf.service;

import com.alibaba.fastjson.JSON;
import com.wf.dao.ESPojo.ESArticle;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class ArticleEsService {

    @Resource
    private RestHighLevelClient restHighLevelClient;
    private static final String INDEX_NAME = "article_index"; // 索引名

    //ik 分词器
    public List<ESArticle> searchByKeyword(String keyword) throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 构建 match 查询:默认对 "title" 和 "content" 分词搜索(可指定字段)
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", keyword)
                .analyzer("ik_max_word"); // 明确指定分词器(或依赖 mapping 配置)
        sourceBuilder.query(matchQuery);

        request.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        // 解析结果
        List<ESArticle> result = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            result.add(JSON.parseObject(hit.getSourceAsString(), ESArticle.class));
        }
        return result;
    }

    // 创建索引(含 IK 分词配置)
    public boolean createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);

        // 配置 mapping(指定 IK 分词)
        XContentBuilder mapping = XContentFactory.jsonBuilder()
            .startObject()
                .startObject("properties")
                    // title 字段:索引用 ik_max_word,搜索用 ik_smart
                    .startObject("title")
                        .field("type", "text")
                        .field("analyzer", "ik_max_word")
                        .field("search_analyzer", "ik_smart")
                    .endObject()
                    // content 字段:同上
                    .startObject("content")
                        .field("type", "text")
                        .field("analyzer", "ik_max_word")
                        .field("search_analyzer", "ik_smart")
                    .endObject()
                    // summary 概述字段
                    .startObject("content")
                        .field("type", "text")
                        .field("analyzer", "ik_max_word")
                        .field("search_analyzer", "ik_smart")
                    .endObject()
                    // author
                    .startObject("author")
                        .field("type","text")
                        .field("analyzer","ik_max_word")
                        .field("search_analyzer","ik_smart")
                    .endObject()
                    // createTime 字段
                    .startObject("createTime")
                        .field("type", "long")
                    .endObject()
                .endObject()
            .endObject();
        request.mapping(String.valueOf(mapping));

        // 执行创建
        CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        return response.isAcknowledged();
    }

    // 判断索引是否存在
    public boolean existsIndex() throws IOException {
        IndicesExistsRequest request = new IndicesExistsRequest(INDEX_NAME);
//        return restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        return true;
    }

    // 删除索引
    public boolean deleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(INDEX_NAME);
        return restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged();
    }

    // 新增文档
    public String addDocument(ESArticle article) throws IOException {
        IndexRequest request = new IndexRequest(INDEX_NAME)
                .id(article.getId()) // 自定义 ID,若不填则 ES 自动生成
                .source(JSON.toJSONString(article), XContentType.JSON);

        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        return response.getId(); // 返回 ES 生成的 ID(若自定义则和入参一致)
    }

    // 修改文档(根据 ID 更新)
    public boolean updateDocument(ESArticle article) throws IOException {
        UpdateRequest request = new UpdateRequest(INDEX_NAME, article.getId())
                .doc(JSON.toJSONString(article), XContentType.JSON);

        UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        return response.getResult() != null;
    }

    // 删除文档(根据 ID 删除)
    public boolean deleteDocument(String docId) throws IOException {
        DeleteRequest request = new DeleteRequest(INDEX_NAME, docId);
        DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        return response.getResult() != null;
    }

    // 查询文档(根据 ID 查询)
    public ESArticle getDocument(String docId) throws IOException {
        GetRequest request = new GetRequest(INDEX_NAME, docId);
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        if (response.isExists()) {
            return JSON.parseObject(response.getSourceAsString(), ESArticle.class);
        }
        return null;
    }
}

第六步,测试

java 复制代码
    @Resource
    private ArticleEsService articleEsService;

    // 测试创建索引
    @Test
    void testCreateIndex() throws IOException {
        boolean success = articleEsService.createIndex();
        System.out.println("创建索引结果:" + success); // 期望 true
    }
    // 测试新增文档
    @Test
    void testAddDocument() throws IOException {
        ESArticle article = new ESArticle();
        article.setId("1");
        article.setTitle("Spring Boot 集成 Elasticsearch 7.6.1");
        article.setContent("详细讲解如何在 Spring Boot 中使用 Elasticsearch,包含 IK 分词验证...");
        article.setCreateTime(System.currentTimeMillis());

        String docId = articleEsService.addDocument(article);
        System.out.println("新增文档 ID:" + docId); // 期望 "1"
    }
    // 测试分词查询(验证 IK)
    @Test
    void testSearchByKeyword() throws IOException {
        List<ESArticle> articles = articleEsService.searchByKeyword("Spring Boot");
        System.out.println("查询结果:" + articles.size()); // 期望 1
        articles.forEach(System.out::println);
    }

使用 head 查看创建情况

相关推荐
optimistic_chen20 分钟前
【Java EE进阶 --- SpringBoot】Mybatis - plus 操作数据库
数据库·spring boot·笔记·java-ee·mybatis·mybatis-plus
yuuki23323327 分钟前
【C语言】文件操作(附源码与图片)
c语言·后端
IT_陈寒30 分钟前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
无名之辈J1 小时前
系统崩溃(OOM)
后端
来旺1 小时前
互联网大厂Java面试全解析及三轮问答专项
java·数据库·spring boot·安全·缓存·微服务·面试
码农刚子1 小时前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
间彧1 小时前
Java ConcurrentHashMap如何合理指定初始容量
后端
摇滚侠1 小时前
Spring Boot 3零基础教程,yml文件中配置和类的属性绑定,笔记15
spring boot·redis·笔记
thginWalker1 小时前
使用Spring Boot构建消息通信层
spring boot
lang201509281 小时前
Spring Boot 外部化配置最佳实践指南
java·spring boot