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

相关推荐
香饽饽~、38 分钟前
【第十一篇】SpringBoot缓存技术
java·开发语言·spring boot·后端·缓存·intellij-idea
程序员爱钓鱼2 小时前
Go语言实战指南 —— Go中的反射机制:reflect 包使用
后端·google·go
ℳ₯㎕ddzོꦿ࿐2 小时前
Spring Boot 集成 MinIO 实现分布式文件存储与管理
spring boot·分布式·后端
G皮T6 小时前
【Elasticsearch】全文检索 & 组合检索
大数据·elasticsearch·搜索引擎·全文检索·match·query·组合检索
ai小鬼头7 小时前
百度秒搭发布:无代码编程如何让普通人轻松打造AI应用?
前端·后端·github
考虑考虑7 小时前
@FilterRegistration和@ServletRegistration注解
spring boot·后端·spring
一只叫煤球的猫7 小时前
🔥 同事混用@Transactional和TransactionTemplate被我怼了,三种事务管理到底怎么选?
java·spring boot·后端
你的人类朋友9 天前
(●'◡'●)从Dockerfile快速入门Docker Compose
后端
GetcharZp9 天前
「神器推荐」Rclone:轻松玩转云端存储,FTP 也能飞起来!
后端
华子w9089258599 天前
基于 SpringBoot+JSP 的医疗预约与诊断系统设计与实现
java·spring boot·后端