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 查看创建情况

相关推荐
2301_32241428047 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
金銀銅鐵9 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
念何架构之路9 小时前
go-grpc设计思想
开发语言·后端·golang
system_error_x10 小时前
SpringBoot 集成 Thymeleaf 简洁入门
java·spring boot·后端
Elastic 中国社区官方博客11 小时前
我们如何通过 70 多个拉取请求,将 OpenTelemetry Java agent 迁移到 invokedynamic
java·大数据·开发语言·elasticsearch·搜索引擎·全文检索·es
步行cgn12 小时前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
码事漫谈12 小时前
AI 读你的提示词,其实很没耐心
后端
用户83562907805113 小时前
如何使用 Python 格式化 Excel 单元格中的长文本
后端·python
我命由我1234513 小时前
Python 开发 - Python 的 pathlib
java·开发语言·后端·python·学习·java-ee·学习方法
IT_陈寒13 小时前
Java性能优化完全指南
前端·人工智能·后端