欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Elasticsearch CRUD 使用说明

程序员文章站 2022-07-09 19:14:46
...

此文章是给有所基础的人看
最最基础请看另一篇安装与介绍(点此链接,自动跳转)

/* 文章结尾有完整 CRUD demo*/

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

application.properties文件配置:

spring.data.elasticsearch.repositories.enabled = true
spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300

首先我们准备好实体类:

 public class Item {
    private Long id;
    private String title; //标题
    private String category;// 分类
    private String brand; // 品牌
    private Double price; // 价格
    private String images; // 图片地址
}

1. javaBean:

package com.czxy.domain;

import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import javax.persistence.*;

@Document(indexName = "product",type = "product", shards = 1, replicas = 0)
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "pid")
    private Integer id;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String pname;
    @Field(type = FieldType.Double)
    private Double price;
    @Field(type = FieldType.Integer)
    private Integer cid;
	
    private Category category;

	 //get set 方法省略......
}


package com.czxy.domain;

import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import javax.persistence.Column;
import javax.persistence.Id;


@Document(indexName = "category",type = "category", shards = 1, replicas = 0)
public class Category {


    @Id
    @Column(name = "cid")
    private Integer id;
    //不分词
    @Field(type = FieldType.Keyword)
    private String cname;

   //get set 方法省略......

    
}
package com.czxy.dao;
import com.czxy.domain.Product;
import tk.mybatis.mapper.common.Mapper;

@org.apache.ibatis.annotations.Mapper
public interface ProductMapper extends Mapper<Product> {
}

/***************************/
package com.czxy.dao;


import com.czxy.domain.Category;
import tk.mybatis.mapper.common.Mapper;

@org.apache.ibatis.annotations.Mapper
public interface CateGoryMapper extends Mapper<Category> {
}

package com.czxy.domain.vo;

import com.czxy.es.pojo.EsProduct;

import java.util.List;

public class EasyUIResult<T> {
	private long total;
	private List<T> rows;
  //get set 方法省略......
	
	 
}

1.2.Repository(后缀是Repository,继承ElasticsearchRepository)

package com.czxy.es;
import com.czxy.domain.Product;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
//第一个参数是:实体类
//第二个参数是:实体类的id字段的属性
public interface ProductRepository extends ElasticsearchRepository <Product,Integer>{
}

2.业务层 查询

package com.czxy.service;


import com.czxy.dao.CateGoryMapper;
import com.czxy.dao.ProductMapper;
import com.czxy.domain.Category;
import com.czxy.domain.Product;
import com.czxy.domain.vo.EasyUIResult;


import com.czxy.es.ProductRepository;

import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;

/**
* @author Fang
* @create 2018-10-11 11:13
* @desc
**/
@Service
@Transactional
public class ProductService {

  @Autowired
  private ProductMapper productMapper;
  @Autowired
  private CateGoryMapper cateGoryMapper;
   //es 所用操作类
  @Autowired
  private ProductRepository productRepository;

      /**
      *@author Fang
      *@create 2018/10/13 17:11
      *@desc  查询
      **/
  
      public EasyUIResult<Product> findAll(Integer page, Integer rows,String pname) {
          NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
          //Boolean
          BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  
          //为空  查询所有
          if (StringUtils.isBlank(pname)||pname.equals("null")){
  
          }else{
              //不为空    通配符查询
              WildcardQueryBuilder pnameBuilder1 = QueryBuilders.wildcardQuery("pname", "*" + pname + "*");
              MatchQueryBuilder pnameBuilder2 = QueryBuilders.matchQuery("pname",pname);
  	    
  				//不分词查询  				
              MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("category.cname", pname);
  
              boolQuery.should(pnameBuilder1).should(pnameBuilder2).should(matchPhraseQueryBuilder);
  
          }
          // 执行分页
          queryBuilder.withPageable(PageRequest.of(page-1,rows));
          // 执行查询
          queryBuilder.withQuery(boolQuery);
          Page<Product> list = productRepository.search(queryBuilder.build());
          //自定义EasyUi中的Datagrid返回集合
          EasyUIResult<Product> result = new EasyUIResult<>();
          result.setTotal(list.getTotalElements());
          result.setRows(list.getContent());
          return result;
      }
   }
***不分词查询***
查询条件:

MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("数据库中名称", 传过来的值);

(二)聚合

聚合可以让我们极其方便的实现对数据的统计、分析。例如:
• 什么品牌的手机最受欢迎?
• 这些手机的平均价格、最高价格、最低价格?
• 这些手机每月的销售情况如何?
实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时搜索效果。
5.6.1 基本概念
Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫桶,一个叫度量:
桶(bucket)
桶的作用,是按照某种方式对数据进行分组,每一组数据在ES中称为一个桶,例如我们根据国籍对人划分,可以得到中国桶、英国桶,日本桶……或者我们按照年龄段对人进行划分:010,1020,2030,3040等。
Elasticsearch中提供的划分桶的方式有很多:
• Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
• Histogram Aggregation:根据数值阶梯分组,与日期类似
• Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
• Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
• ……

综上所述,我们发现bucket aggregations 只负责对数据进行分组,并不进行计算,因此往往bucket中往往会嵌套另一种聚合:metrics aggregations即度量

(三)度量(metrics)

分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为度量
比较常用的一些度量聚合方式:
• Avg Aggregation:求平均值
• Max Aggregation:求最大值
• Min Aggregation:求最小值
• Percentiles Aggregation:求百分比
• Stats Aggregation:同时返回avg、max、min、sum、count等
• Sum Aggregation:求和
• Top hits Aggregation:求前几
• Value Count Aggregation:求总数
• ……

注意:在ES中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词。这里我们将color和make这两个文字类型的字段设置为keyword类型,这个类型不会被分词,将来就可以参与聚合

(四)聚合为桶

桶就是分组,比如这里我们按照品牌brand进行分组:

public void testAgg(){
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    // 不查询任何结果
    queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
    // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
    queryBuilder.addAggregation(
        AggregationBuilders.terms("brands").field("brand"));
    // 2、查询,需要把结果强转为AggregatedPage类型
    AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
    // 3、解析
    // 3.1、从结果中取出名为brands的那个聚合,
    // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
    StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
    // 3.2、获取桶
    List<StringTerms.Bucket> buckets = agg.getBuckets();
    // 3.3、遍历
    for (StringTerms.Bucket bucket : buckets) {
        // 3.4、获取桶中的key,即品牌名称
        System.out.println(bucket.getKeyAsString());
        // 3.5、获取桶中的文档数量
        System.out.println(bucket.getDocCount());
    }

}

(五)嵌套聚合,求平均值

代码:

public void testSubAgg(){
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    // 不查询任何结果
    queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
    // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
    queryBuilder.addAggregation(
        AggregationBuilders.terms("brands").field("brand")
        .subAggregation(AggregationBuilders.avg("priceAvg").field("price")) // 在品牌聚合桶内进行嵌套聚合,求平均值
    );
    // 2、查询,需要把结果强转为AggregatedPage类型
    AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
    // 3、解析
    // 3.1、从结果中取出名为brands的那个聚合,
    // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
    StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
    // 3.2、获取桶
    List<StringTerms.Bucket> buckets = agg.getBuckets();
    // 3.3、遍历
    for (StringTerms.Bucket bucket : buckets) {
        // 3.4、获取桶中的key,即品牌名称  3.5、获取桶中的文档数量
        System.out.println(bucket.getKeyAsString() + ",共" + bucket.getDocCount() + "台");

 

   // 3.6.获取子聚合结果:
    InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg");
    System.out.println("平均售价:" + avg.getValue());
}

}
![在这里插入图片描述](https://img-blog.csdn.net/20181015183045728?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjYzMzEzMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

详细说明:

概念 说明
索引库(indices) indices是index的复数,代表许多的索引,
类型(type) 类型是模拟mysql中的table概念,一个索引库下可以有不同类型的索引,比如商品索引,订单索引,其数据格式不同。不过这会导致索引库混乱,因此未来版本中会移除这个概念
文档(document) 存入索引库原始的数据。比如每一条商品信息,就是一个文档
字段(field) 文档中的属性
映射配置(mappings) 字段的数据类型、属性、是否索引、是否存储等特性
是不是与Lucene中的概念类似。
另外,在Elasticsearch有一些集群相关的概念:
• 索引集(Indices,index的复数):逻辑上的完整索引
• 分片(shard):数据拆分后的各个部分
• 副本(replica):每个分片的复制

要注意的是:Elasticsearch本身就是分布式的,因此即便你只有一个节点,Elasticsearch默认也会对你的数据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。

// 完整 CRUD demo示例

package com.czxy.domain;

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;

/**
 * @author Fang
 * @create 2018-09-28 15:27
 * @desc 实体类
 **/
@Document(indexName = "item",type = "docs",shards = 1,replicas = 0)
public class Item {

    @Id
    private Long id;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String title; //标题
    @Field(type = FieldType.Keyword)
    private String category;// 分类
    @Field(type = FieldType.Keyword)
    private String brand; // 品牌
    @Field(type = FieldType.Double)
    private Double price; // 价格
    @Field(type = FieldType.Keyword,index = false)
    private 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(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;
    }

    public Item() {
    }

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

package com.czxy.dao;

import com.czxy.domain.Item;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
     //自定义查询 
    List<Item>  findByCategoryAndPrice(String category,Double price);
      List<Item> findByPriceBetween(double price1,double  price2);
}

package com.czxy;
import com.czxy.dao.ItemRepository;
import com.czxy.domain.Item;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.AggregationPhase;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
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.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import java.lang.annotation.Native;
import java.util.ArrayList;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class EsDemoApplicationTests {
    @Autowired
    private ElasticsearchTemplate template;

    @Autowired
    private ItemRepository itemRepository;

    /**
     * @author Fang
     * @create 2018/9/28 16:20
     * @desc 创建索引
     **/
    @Test
    public void contextLoads() {
        // 创建索引,会根据Item类的@Document注解信息来创建
        template.createIndex(Item.class);
        // 配置映射,会根据Item类中的id、Field等字段来自动完成映射
        template.putMapping(Item.class);
    }

    /**
     * @author Fang
     * @create 2018/9/28 17:23
     * @desc 删除索引
     **/

    @Test
    public void deleteIndex() {
        template.deleteIndex(Item.class);
        //根据索引名字删除
//        template.deleteIndex("item");
    }

    /**
     * @author Fang
     * @create 2018/9/28 17:25
     * @desc 新增数据
     **/
    @Test
    public void index() {
        Item item = new Item(1L, "小米手机7", " 手机",
                "小米", 3499.00, "http://image.baidu.com/13123.jpg");
        itemRepository.save(item);
    }

    /**
     * @author Fang
     * @create 2018/9/28 17:27
     * @desc 批量新增
     **/
    @Test
    public void indexList() {
        ArrayList<Item> list = new ArrayList<>();
        list.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.baidu.com/13123.jpg"));
        list.add(new Item(3L, "华为META10", " 手机", "华为", 4499.00, "http://image.baidu.com/13123.jpg"));
        // 接收对象集合,实现批量新增
        itemRepository.saveAll(list);

    }

    /**
     * @author Fang
     * @create 2018/9/28 17:29
     * @desc 修改
     * 修改和新增是同一个接口,区分的依据就是id。
     **/

    @Test
    public void update() {
        Item item = new Item(1L, "苹果XSMax", " 手机",
                "小米", 3499.00, "http://image.baidu.com/13123.jpg");
        itemRepository.save(item);
    }


    /**
     * @author Fang
     * @create 2018/9/28 20:06
     * @desc 查询
     **/

    @Test
    public void testQuery() {
        //查询所有
        Iterable<Item> all = itemRepository.findAll(Sort.by("price").descending());
        for (Item item : all) {
            System.out.println(item);
        }
    }

    /**
     * @author Fang
     * @create 2018/9/28 20:17
     * @desc 自定义查询
     **/
    @Test
    public void findByNameAndPrice() {
        List<Item> list = itemRepository.findByCategoryAndPrice("手机", 3499.00);
        for (Item item : list) {
            System.out.println(item);
        }
    }

    /**
     * @author Fang
     * @create 2018/9/28 20:28
     * @desc 区间数查询
     **/

    @Test
    public void queryByPriceBetween() {
        List<Item> list = itemRepository.findByPriceBetween(4000.00, 5000.00);
        for (Item item : list) {
            System.out.println(item);
        }
    }

    /**
     * @author Fang
     * @create 2018/9/28 20:32
     * @desc 查询
     **/
    @Test
    public void pageSearch() {

        //构建查询条件

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //添加分词查询
        builder.withQuery(QueryBuilders.matchQuery("title", "华为"));
        //搜索获取结果
        Page<Item> list = itemRepository.search(builder.build());
        //总条数
        System.out.println(list.getTotalElements());
        for (Item it : list) {
            System.out.println(it);
        }
    }

    /**
     * @author Fang
     * @create 2018/9/28 20:39
     * @desc termQuery:功能更强大,除了匹配字符串以外,还可以匹配
     **/
    @Test
    public void testTermQuery() {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.termQuery("price", 3499.00));
        Page<Item> list = itemRepository.search(queryBuilder.build());
        for (Item it : list) {
            System.out.println(it);
        }
    }

    @Test
    public void indexList1() {
        List<Item> list = new ArrayList<>();
        list.add(new Item(4L, "小米手机7facebook", "手机", "小米", 3299.00, "http://image.baidu.com/13123.jpg"));
        list.add(new Item(5L, "坚果手机R1facebook", "手机", "锤子", 3699.00, "http://image.baidu.com/13123.jpg"));
        list.add(new Item(6L, "华为META10facebook", "手机", "华为", 4499.00, "http://image.baidu.com/13123.jpg"));
        list.add(new Item(7L, "小米Mix2Sfacebook", "手机", "小米", 4299.00, "http://image.baidu.com/13123.jpg"));
        list.add(new Item(8L, "荣耀V10facebook", "手机", "华为", 2799.00, "http://image.baidu.com/13123.jpg"));
        // 接收对象集合,实现批量新增
        itemRepository.saveAll(list);
    }

    /**
     * @author Fang
     * @create 2018/9/28 20:42
     * @desc 查询
     **/

    @Test
    public void testBooleanQuery() {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title", "华为")).must(QueryBuilders.matchQuery("brand", "华为")));
        //查找
        Page<Item> list = itemRepository.search(queryBuilder.build());
        System.out.println("总条数:" + list.getTotalElements());
        for (Item it : list) {
            System.out.println(it);
        }


    }

    /**
     * @author Fang
     * @create 2018/9/28 20:48
     * @desc 模糊查询
     **/
    @Test

    public void testFuzzyQuery() {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.fuzzyQuery("title", "faceoooo"));
        Page<Item> list = itemRepository.search(queryBuilder.build());
        System.out.println("总条数:" + list.getTotalElements());
        for (Item it : list) {
            System.out.println(it);
        }

    }

    /**
     * @author Fang
     * @create 2018/9/28 20:51
     * @desc 分页查询
     **/
    @Test
    public void testPageSearch() {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
        //分页
        int page = 0;
        int size = 3;
        queryBuilder.withPageable(PageRequest.of(page, size));
        //搜索
        Page<Item> page1 = itemRepository.search(queryBuilder.build());
        //总条数
        System.out.println("总条数:" + page1.getTotalElements());
        //总页数
        System.out.println(page1.getTotalPages());
        // 当前页
        System.out.println(page1.getNumber());
        //每页大小
        System.out.println(page1.getSize());
        //所有数据
        for (Item item : page1) {
            System.out.println(item);
        }

    }

    /**
     * @author Fang
     * @create 2018/9/28 21:27
     * @desc 排序
     **/
    @Test
    public void searchAndSort() {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
        //排序

        queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));

        Page<Item> page = itemRepository.search(queryBuilder.build());
        for (Item item : page) {
            System.out.println(item);
        }
    }

    /**
     * @author Fang
     * @create 2018/9/29 8:59
     * @desc 聚合   bucket
     **/
    @Test
    public void testBuckey() {
        //自定义查询
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand"));
        //查询
        Page<Item> page = itemRepository.search(queryBuilder.build());
        //强转成子类
        AggregatedPage<Item> aggregatedPage = (AggregatedPage<Item>) page;
        //通过健获取值
        Aggregation aggregation = aggregatedPage.getAggregation("brands");
        //转成
        StringTerms terms = (StringTerms) aggregation;

        List<StringTerms.Bucket> buckets = terms.getBuckets();
        for (StringTerms.Bucket bucket : buckets) {
            //名称
            System.out.print(bucket.getKeyAsString() + "\t");
            //数量
            System.out.println(bucket.getDocCount());


        }
    }

        /**
         *@author Fang
         *@create 2018/9/29 9:22
         *@desc   分组 求平均值   terms + avg
         **/
        @Test
        public void testMetri(){
            NativeSearchQueryBuilder queryBuilder1 = new NativeSearchQueryBuilder();
            queryBuilder1.addAggregation(AggregationBuilders.terms("brands").field("brand")
                       .subAggregation(AggregationBuilders.avg("priceAvg").field("price")));

            AggregatedPage<Item> aggregatedPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder1.build());

            StringTerms brands = (StringTerms) aggregatedPage.getAggregation("brands");

            List<StringTerms.Bucket> buckets = brands.getBuckets();
            for(StringTerms.Bucket bu:buckets){
                System.out.print(bu.getKeyAsString()+"\t"+bu.getDocCount()+"\t");

               InternalAvg  avg=(InternalAvg)bu.getAggregations().asMap().get("priceAvg");
                System.out.println(avg.getValue());
            }

        }



}