SpringBoot整合SpringData ES

本文介绍SpringDataElasticsearch的基础知识及如何在SpringBoot项目中整合并使用它。通过具体示例,演示如何创建索引库、进行文档操作及执行复杂查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 什么是Spring Data ElasticSearch

Spring Data Elasticsearch是Spring Data项目下的一个子模块。

查看 Spring Data的官网:http://projects.spring.io/spring-data/
Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch操作,将原始操作elasticSearch的客户端API 进行封装 。Spring Data为Elasticsearch项目提供集成搜索引擎。Spring Data Elasticsearch POJO的关键功能区域为中心的模型与Elastichsearch交互文档和轻松地编写一个存储库数据访问层。

官方网站:http://projects.spring.io/spring-data-elasticsearch

###1.SpringData ES说明

在后期项目开发中,XML整合方式已经落伍了,目前市面上的项目都是拥抱SpringBoot框架,来实现项目的构建,那么课程就使用SpringBoot完成Spring Data ES的整合。就不用管传统applicationContext.xml整合方式

2.SpringData ES整合步骤

2.1.准备搜索的服务工程

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>easygo</artifactId>
        <groupId>com.bruce.easygo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>easygo-search-service</artifactId>

    <!--导入项目中的依赖-->
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--引入实体层-->
        <dependency>
            <groupId>com.bruce.easygo</groupId>
            <artifactId>easygo-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

        <!-- Eureka客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>com.bruce.easygo</groupId>
            <artifactId>easygo-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>
server.port=9009

# 配置Eureka信息
# 服务的名字,注册到注册中心的名字,后期消费者来根据名字调用服务 可以重复
spring.application.name=easygo-search-service
# EurekaServer地址
eureka.client.service-url.defaultZone=http://127.0.0.1:9001/eureka
# 当调用getHostname获取实例的hostname时,返回ip而不是host名称
eureka.instance.prefer-ip-address=true
# 指定自己的ip信息,不指定的话会自己寻找
eureka.instance.ip-address=127.0.0.1
# 执行当前服务的应用ID  不可以重复  标识的是每一个具体的的服务
eureka.instance.instance-id=easygo-search-service-9009

2.2.项目中引入依赖

<!--导入Spring Data ES依赖-->
<!--spring-data elasticsearch-->
	<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2.3.配置Spring Data ES的配置信息

# Spring Data elasticsearch配置
spring.data.elasticsearch.cluster-name=elasticsearch
# 连接地址
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
#设置连接超时时间
spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s

2.4.测试ES的连接

package com.easygo.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @BelongsProject: easygo
 * @BelongsPackage: com.easygo.test
 * @Author: bruceliu
 * @QQ:1241488705
 * @CreateTime: 2020-04-10 15:20
 * @Description: TODO
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestES {

    //如果要操作Redis,需要获取一个 RedisTemplate
    //如果要操作ES,需要获取 ElasticsearchTemplate,天下我有!
    @Resource
    ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 01-测试工具类
     */
    @Test
    public void testConn(){
        System.out.println("ES操作的工具类:"+elasticsearchTemplate);
    }

    /**
     *02-创建一个索引库? Goods索引库,实际的项目搜索的是商品数据!
     */
    @Test
    public void testCreateIndex(){
        //创建索库
        elasticsearchTemplate.createIndex("goodsindexs");
        System.out.println("测试创建索引库");
    }

}

3.使用面向对象思想创建索引库和Mapping

3.1.准备一个实体类,索引库对应

package com.easygo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @BelongsProject: easygo
 * @BelongsPackage: com.easygo.pojo
 * @Author: bruceliu
 * @QQ:1241488705
 * @CreateTime: 2020-04-10 15:55
 * @Description: 商品实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Goods implements Serializable {

    private static final long serialVersionUID = 8972263575352384971L;

    private Integer id;
    private String seller_id; //卖家ID
    private String goods_name;  //商品的标题
    private Integer default_item_id; //默认上架商品ID
    private String audit_status; //当前状态
    private String is_marketable; //是否上架
    private Integer brand_id;  //商品的品牌ID
    private String caption;  //商品的副标题
    private Integer category1_id;
    private Integer category2_id;
    private Integer category3_id;
    private String small_pic;  //商品的小图
    private Double price;  //商品的价格
    private Integer type_template_id;
    private String is_enable_spec;
    private String is_delete;
}

3.2. 给实体类加一些注解(Spring Data ES注解),配置Mapping规则的注解

<!--导入Spring Data ES依赖 把它导入到实体类中-->
    <!--spring-data elasticsearch-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
package com.easygo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.io.Serializable;

/**
 * @BelongsProject: easygo
 * @BelongsPackage: com.easygo.pojo
 * @Author: bruceliu
 * @QQ:1241488705
 * @CreateTime: 2020-04-10 15:55
 * @Description: 商品实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
//文档对象是(索引库名,类型)
@Document(indexName = "goodsindex",type = "goods")
public class Goods implements Serializable {

    private static final long serialVersionUID = 8972263575352384971L;

    //字段的配置 类型 是否索引  是否存储
    @Field(store = true,index = false,type = FieldType.Integer)
    private Integer id;

    private String seller_id; //卖家ID

    @Field(store = true,analyzer = "ik_max_word",index = true,searchAnalyzer ="ik_max_word",type = FieldType.Text)
    private String goods_name;  //商品的标题

    private Integer default_item_id; //默认上架商品ID
    private String audit_status; //当前状态
    private String is_marketable; //是否上架

    @Field(store = true,index = false,type = FieldType.Integer)
    private Integer brand_id;  //商品的品牌ID

    @Field(store = true,analyzer = "ik_max_word",index = true,searchAnalyzer ="ik_max_word",type = FieldType.Text)
    private String caption;  //商品的副标题

    private Integer category1_id;
    private Integer category2_id;
    private Integer category3_id;

    @Field(store = true,index = false,type = FieldType.Text)
    private String small_pic;  //商品的小图

    @Field(store = true,index = false,type = FieldType.Double)
    private Double price;  //商品的价格

    private Integer type_template_id;
    private String is_enable_spec;
    private String is_delete;
}

package com.easygo.test;

import com.easygo.client.GoodsClient;
import com.easygo.pojo.Goods;
import com.easygo.service.GoodsService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @BelongsProject: easygo
 * @BelongsPackage: com.easygo.test
 * @Author: bruceliu
 * @QQ:1241488705
 * @CreateTime: 2020-04-10 15:20
 * @Description: TODO
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestES {

    //如果要操作Redis,需要获取一个 RedisTemplate
    //如果要操作ES,需要获取 ElasticsearchTemplate,天下我有!
    @Resource
    ElasticsearchTemplate elasticsearchTemplate;

    @Resource
    GoodsClient goodsClient;

    @Autowired
    GoodsService goodsService;

    /**
     * 01-测试工具类
     */
    @Test
    public void testConn(){
        System.out.println("ES操作的工具类:"+elasticsearchTemplate);
    }

    /**
     *02-创建一个索引库? Goods索引库,实际的项目搜索的是商品数据!
     */
    @Test
    public void testCreateIndex(){
        //创建索库,索引库的名字是??
        elasticsearchTemplate.createIndex(Goods.class);
        System.out.println("测试创建索引库成功~");
        elasticsearchTemplate.putMapping(Goods.class);//因为类上面有注解
        System.out.println("创建Goods的Mapping完成");
    }

    /**
     * 新增数据库中的数据到ES索引库中
     */
    @Test
    public void testAddDocument(){
        List<Goods> goodsList = goodsClient.getGoods(1);
        for (Goods goods : goodsList) {
            System.out.println("正在导入:"+goods);
        }
        goodsService.saveDocuments(goodsList);
        System.out.println("批量新增索引库数据成功......");
    }

    /**
     * 根据ID查询
     */
    @Test
    public void testgetDocumentById(){
        Goods goods = goodsService.getDocumentById(149187842868047L);
        System.out.println("查询的对象是:"+goods);
    }

    /**
     * 根据ID更新
     */
    @Test
    public void testUpdateById(){
        Goods goods = goodsService.getDocumentById(149187842867986L);
        System.out.println("查询的原对象是:"+goods);
        goods.setGoods_name("阿玛尼装逼神器");
        goods.setCaption("阿玛尼装逼神器,泡妞必备,值得哟拥有");
        goods.setPrice(250.0);
        goodsService.updateDocumentById(goods);
        System.out.println("更新document");
    }

    /**
     * 根据ID删除
     */
    @Test
    public void testDeleteByid(){
        goodsService.deleteDocumentById(149187842867914L);
        System.out.println("删除成功");
    }

    /**
     * 删除所有
     */
    @Test
    public void testDeleteAll(){
        goodsService.deleteAllDocument();
        System.out.println("全部干光了");
    }

    /**
     * 测试关键词查询01  条件查询分页
     */
    @Test
    public void testQuery1(){
        int pageIndex=4; //当前页码
        int pageSize=3; //页码大小
        String keywords="手机"; //用户输入的关键词

        //构建一个查询对象
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                //设置查询条件,可以构建多个条件
                .withQuery(QueryBuilders.queryStringQuery(keywords).defaultField("goods_name"))
                //设置分页的信息,页码从0开始计算
                .withPageable(PageRequest.of(pageIndex - 1, pageSize)).build();

        //条件查询分页,返回分页对象
        AggregatedPage<Goods> page = elasticsearchTemplate.queryForPage(searchQuery, Goods.class);
        System.out.println("当前页码:"+pageIndex);
        System.out.println("页面大小:"+pageSize);
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("每页到的数据是:");
        List<Goods> goodsList = page.getContent();
        for (Goods goods : goodsList) {
            System.out.println(goods);
        }

    }

    /**
     * 多条件搜索 分页
     */
    @Test
    public void testtestQuery2(){
        int pageIndex=1; //当前页码
        int pageSize=3; //页码大小
        String keywords="火爆"; //用户输入的关键词

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        if(keywords!=null&&!"".equals(keywords)){
            builder.withQuery(QueryBuilders.multiMatchQuery(keywords, "goods_name", "caption"));
        }
        //设置分页的信息,页码从0开始计算
        builder.withPageable(PageRequest.of(pageIndex - 1, pageSize));
        NativeSearchQuery searchQuery = builder.build();

        //条件查询分页,返回分页对象
        AggregatedPage<Goods> page = elasticsearchTemplate.queryForPage(searchQuery, Goods.class);
        System.out.println("当前页码:"+pageIndex);
        System.out.println("页面大小:"+pageSize);
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("每页到的数据是:");
        List<Goods> goodsList = page.getContent();
        for (Goods goods : goodsList) {
            System.out.println(goods);
        }
    }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源码小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值