ES7SpringDataElasticsearch配置 最完整的springboot2.2.x.RELEASE整合springDataElasticsearch Elasticsea

本文使用内容    springBoot2.2.5.RELEASE版本   Elasticsearch7.6.2  linux版本的   SpringDataElasticSearch与Springboot版本对应

一、操作准备

1、导入依赖

此处版本

2.2.5.RELEASE
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2、创建application.yml文件

spring:
  elasticsearch:
    rest:
      uris: http://192.168.0.211:9200

此处的ip:端口  是自己的Elasticsearch的,如果为集群可以以逗号(,)隔开

3、创建实体类对象

package cn.cqsw.elasticsearch.pojo;

import org.springframework.data.annotation.Id;
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;

@Document(indexName = "item" , type = "_doc",shards = 1,replicas = 0)
public class Item implements Serializable {
    @Id    //注意此处的@Id必须为springframework包下面的id   import org.springframework.data.annotation.Id;
    Long id;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    String title; //标题
    @Field(type = FieldType.Keyword)
    String category;// 分类
    @Field(type = FieldType.Keyword)
    String brand; // 品牌
    @Field(type = FieldType.Double)
    Double price; // 价格
    @Field(type = FieldType.Keyword,index = false)
    String images; // 图片地址

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getImages() {
        return images;
    }

    public void setImages(String images) {
        this.images = images;
    }

    public Item() {
    }

    public Item(Long id, String title, String category, String brand, Double price, String images) {
        this.id = id;
        this.title = title;
        this.category = category;
        this.brand = brand;
        this.price = price;
        this.images = images;
    }


    @Override
    public String toString() {
        return "Item{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", category='" + category + '\'' +
                ", brand='" + brand + '\'' +
                ", price=" + price +
                ", images='" + images + '\'' +
                '}';
    }

注解参数含义解释

Spring Data通过注解来声明字段的映射属性,有下面的三个注解:

- `@Document` 作用在类,标记实体类为文档对象,一般有四个属性
  - indexName:对应索引库名称
  - type:对应在索引库中的类型   在ElasticSearch7.x中取消了type的概念
  - shards:分片数量,默认5
  - replicas:副本数量,默认1
- `@Id` 作用在成员变量,标记一个字段作为id主键
- `@Field` 作用在成员变量,标记为文档的字段,并指定字段映射属性:
  - type:字段类型,取值是枚举:FieldType
  - index:是否索引,布尔类型,默认是true
  - store:是否存储,布尔类型,默认是false
  - analyzer:分词器名称:ik_max_word    ik分词器内容,看另外一个随笔:https://www.cnblogs.com/TJ21/p/12642242.html

4、创建一个空的Repository的接口  

不明白为什么可以看一些Spring-Data文档

5、创建启动类

@SpringBootApplication
public class ElasticSearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(ElasticSearchApplication.class);
    }
}

6、创建测试

 

 测试   

注意

此处使用  

ElasticsearchRestTemplate   模板原因为 :  ElasticsearchTemplate 模板使用的是使用的 TransportClient 此客户端在ElasticSearch7的版本中不再推荐使用,在8的版本中将被移除,官方建议使用:High Level REST Client (高级Test客户端)
不使用ElasticsearchTemplate 
原因查看官方文档:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.6.RELEASE/reference/html/#elasticsearch.clients.transport

 

使用ElasticsearchRestTemplate   原因:官方文档:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.6.RELEASE/reference/html/#elasticsearch.operations.resttemplate

这样我们使用的就是: High Level REST Client (高级Test客户端)

 

 

使用junit4

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class ElasticisesTest {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private ItemRepository itemRepository;


    @Test
    public void addIndexTest() {
        this.elasticsearchRestTemplate.createIndex(Item.class);
        this.elasticsearchRestTemplate.putMapping(Item.class);
    }


    @Test
    public void deleteIndex() {
        this.elasticsearchRestTemplate.deleteIndex("item");
    }

    /**
     * 新增和批量新增
     */
    @Test
    public void create() {

        /*新增*/
//        Item item = new Item(1L, "小米手机7", " 手机", "小米", 3499.00, "http://image.leyou.com/13123.jpg");
//        this.itemRepository.save(item);

        List<Item> list = new ArrayList<>();
        list.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.leyou.com/123.jpg"));
        list.add(new Item(3L, "华为META10", " 手机", "华为", 4499.00, "http://image.leyou.com/3.jpg"));
        // 接收对象集合,实现批量新增
        this.itemRepository.saveAll(list);
    }


    /**
     * 查询全部
     */
    @Test
    public void find() {
        Optional<Item> item = this.itemRepository.findById(1L);
        System.out.println("item.get() = " + item.get());
    }


    /**
     * 查询并排序
     */
    @Test
    public void findAllSort() {
        Iterable<Item> items = this.itemRepository.findAll(Sort.by("price").descending());

        items.forEach(System.out::println);
    }


    /**
     * 根据title查询
     */
    @Test
    public void findByTitle() {
        Iterable<Item> items = this.itemRepository.findByTitle("手机");
        items.forEach(System.out::println);
    }


    /**
     * 查询价格区间
     */
    @Test
    public void findByPrice() {
        List<Item> byPriceBetween = this.itemRepository.findByPriceBetween(3699d, 4499d);
        byPriceBetween.forEach(System.out::println);
    }


    /**
     * 添加测试数据
     */
    @Test
    public void indexList() {
        List<Item> list = new ArrayList<>();
        list.add(new Item(1L, "小米手机7", "手机", "小米", 3299.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(2L, "坚果手机R1", "手机", "锤子", 3699.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(3L, "华为META10", "手机", "华为", 4499.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(4L, "小米Mix2S", "手机", "小米", 4299.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(5L, "荣耀V10", "手机", "华为", 2799.00, "http://image.leyou.com/13123.jpg"));
        // 接收对象集合,实现批量新增
        itemRepository.saveAll(list);
    }

    /**
     * 通过标题查询
     */
    @Test
    public void testSearch() {
        // 通过查询构建器构建查询条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
        //执行查询
        Iterable<Item> items = this.itemRepository.search(matchQueryBuilder);
        items.forEach(System.out::println);
    }

    @Test
    public void testNative() {
        //构建自定义查询构建器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //添加基本的查询条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
        //执行查询获取分页结果集
        nativeSearchQueryBuilder.withQuery(matchQueryBuilder);

        Page<Item> items = this.itemRepository.search(nativeSearchQueryBuilder.build());
        System.out.println("items.getTotalElements() = " + items.getTotalElements());
        System.out.println("items.getTotalPages() = " + items.getTotalPages());
        items.forEach(System.out::println);

    }


    /**
     * 分页查询
     */

    @Test
    public void testNativeQuery() {
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词查询
        queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));

        // 初始化分页参数
        int page = 0;
        int size = 3;
        // 设置分页参数
        queryBuilder.withPageable(PageRequest.of(page, size));

        // 执行搜索,获取结果
        Page<Item> items = this.itemRepository.search(queryBuilder.build());
        // 打印总条数
        System.out.println(items.getTotalElements());
        // 打印总页数
        System.out.println(items.getTotalPages());
        // 每页大小
        System.out.println(items.getSize());
        // 当前页
        System.out.println(items.getNumber());
        items.forEach(System.out::println);
    }

    @Test
    public void testAggs() {

        //初始化自定义构建查询器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        //添加聚合
        queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand"));

        //添加结果集过滤不包括任何字段
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));

        //执行查询
        AggregatedPage<Item> itemPage = (AggregatedPage<Item>)this.itemRepository.search(queryBuilder.build());


        /*
        解析聚合结果集,根据聚合的类型以及字段类型,要进行强转,不然无法获取桶
         brand-是字符串类型的,聚合类型是词条类型的
        brandAgg-通过聚合名称获取聚合对象
        使用StringTerms强转的时候出现错误
         */

        ParsedStringTerms brandAgg =(ParsedStringTerms) itemPage.getAggregation("brandAgg");

        //获取桶
        List<? extends Terms.Bucket> buckets = brandAgg.getBuckets();

        //遍历输出
        buckets.forEach(bucket -> {
            System.out.println("bucket.getKeyAsString() = " + bucket.getKeyAsString());
            //获取条数
            System.out.println("bucket.getDocCount() = " + bucket.getDocCount());
        });

    }


    /**
     * 子聚合
     */
    @Test
    public void testSubAggs() {

        //初始化自定义构建查询器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        //添加聚合
        queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand").subAggregation(AggregationBuilders.avg("price_avg").field("price")));

        //添加结果集过滤不包括任何字段
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));

        //执行查询
        AggregatedPage<Item> itemPage = (AggregatedPage<Item>)this.itemRepository.search(queryBuilder.build());


        /*
        解析聚合结果集,根据聚合的类型以及字段类型,要进行强转,不然无法获取桶
         brand-是字符串类型的,聚合类型是词条类型的
        brandAgg-通过聚合名称获取聚合对象
        使用StringTerms强转的时候出现错误
         */

        StringTerms brandAgg =(StringTerms) itemPage.getAggregation("brandAgg");

        //获取桶
        List<StringTerms.Bucket> buckets = brandAgg.getBuckets();

        //遍历输出
        buckets.forEach(bucket -> {
            System.out.println("bucket.getKeyAsString() = " + bucket.getKeyAsString());
            //获取条数
            System.out.println("bucket.getDocCount() = " + bucket.getDocCount());
            
            //获取子聚合的map集合:key-聚合名称,value-对应的子聚合对象
            Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();
            /*
            以前使用的InternalAvg强转出现转换异常
             */
            ParsedAvg price_avg =(ParsedAvg) stringAggregationMap.get("price_avg");


            System.out.println("price_avg.getValue() = " + price_avg.getValue());
        });

    }

}

虽然为转载,但来自同一作者

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BaldHead's Blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值