Elasticsearch 7.17.6 windows环境下学习

下载地址

Elasticsearch 7.17.6
Kibana 7.17.6

ES 配置

配置ES的JDK11,指向解压包
ES_JAVA_HOME
在这里插入图片描述

修改ES启动的运存

修改config目录里的 jvm.options 文件
防止开发时候电脑太卡

-Xms128m
-Xmx512m

在这里插入图片描述

启动kibana

bin 目录下的 kibana.bat ,启动时间比较久

查看node版本
在这里插入图片描述

设置为中文

config目录下单 kibana.yml
最后一行加上,然后重启服务

i18n.locale: "zh-CN"

安装 IK 分词

下载地址
解压到目录里 elasticsearch-7.17.6\plugins\ik
安装好后重启ES服务

配置自己的词典

1.进入 elasticsearch-7.17.6\plugins\ik\config 目录,随便复制一个dic后缀的文件,修改名字为 mydic.dic。

2.编辑 mydic.dic 文件。
在这里插入图片描述
3.重启ES服务
4.智能分词里就有自己添加的词
在这里插入图片描述

去掉需要密码的提示

目录 elasticsearch-7.17.6\config\elasticsearch.yml 最后一行加上:
xpack.security.enabled: false

加上日志输出请求

application.yml末尾加上

logging:
  level:
    tracer: TRACE

kibana 控制台

使用文档

# 查看健康状态
GET /_cat/health?v
# 查看节点
GET /_cat/nodes?v
# 查看索引
GET /_cat/indices?v

# 新建索引
PUT /my_test
# 删除索引
DELETE /my_test

# ik 分词测试
GET /_analyze?pretty
{
"analyzer" : "ik_max_word",
"text": "中华人民共和国国歌"
}

ES直接操作学习

融入JAVA 项目

官方文档

es和springboot版本对比

  1. 测试类test目录下的JAVA包名和项目src的一样
  2. 查询 cluster_name,http://127.0.0.1:9200/_cluster/health?pretty
  3. 代码实例
  4. 语法教程

JAVA代码样例

public class ElasticsearchRepositoryTest extends BaseTest {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GoodsRepository goodsEsRepository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 导入测试数据,从mysql中导入测试数据至es
     */
    @Test
    public void importAllData() {
        // 查询所有数据
        List<Goods> lists = goodsMapper.findAll();
        // 保存所有数据只ES中
        goodsEsRepository.saveAll(lists);
        System.out.println("ok");
    }

    /**
     * 添加文档
     */
    @Test
    public void save() {
//        PUT /goods/_doc/1?timeout=1m
//        {"_class":"com.sky.demo.domain.Goods","id":1,"title":"Apple iPhone 13 ProMax 5G全网通手机","price":8999.0,"stock":100,"saleNum":1,"categoryName":"手机","brandName":"Apple","status":0,"createTime":"2022-09-23 07:53:43"}

        Goods goods = new Goods(1L, "Apple iPhone 13 ProMax 5G全网通手机", new BigDecimal(8999), 100, 1, "手机", "Apple", 0, new Date());
        goodsEsRepository.save(goods);
    }

    /**
     * 批量添加数据
     */
    @Test
    public void saveAll() {
        List<Goods> goodsList = new ArrayList<>();
        goodsList.add(new Goods(2L, "title2", new BigDecimal(12), 1, 1, "category2", "brandName2", 0, new Date()));
        goodsList.add(new Goods(3L, "title3", new BigDecimal(12), 1, 1, "category3", "brandName3", 0, new Date()));
        goodsList.add(new Goods(4L, "title4", new BigDecimal(12), 1, 1, "category4", "brandName4", 0, new Date()));
        goodsEsRepository.saveAll(goodsList);
    }

    /**
     * 根据编号查询
     */
    @Test
    public void findById() {
//        GET '/goods/_doc/536563'
        Optional<Goods> optional = goodsEsRepository.findById(536563L);
        System.out.println(optional.orElse(null));
    }

    /**
     * 查询所有
     *
     */
    @Test
    public void findAll() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
        Iterable<Goods> list = goodsEsRepository.findAll();
        for (Goods item : list) {
            System.out.println(item);
        }
    }

    /**
     * 分页查询
     */
    @Test
    public void findAllByPage() {
        // 数据太多了分页查询
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from":0,"size":10
//        }
        PageRequest pageRequest = PageRequest.of(0, 10);
        Iterable<Goods> list = goodsEsRepository.findAll(pageRequest);
        for (Goods item : list) {
            System.out.println(item);
        }
    }

    /**
     * 排序查询
     */
    @Test
    public void findAllBySort() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from":0,"size":10
//                ,"sort":[{"price":{"order":"desc","mode":"min"}}]
//        }
        Iterable<Goods> list = goodsEsRepository.findAll(Sort.by(Sort.Direction.DESC, "price"));
        for (Goods item : list) {
            System.out.println(item);
        }
    }

    /**
     * 根据ID批量查询
     */
    @Test
    public void findAllById() {
//        GET /_mget
//        {
//            "docs": [{
//            "_index": "goods",
//                    "_id": "536563"
//        }, {
//            "_index": "goods",
//                    "_id": "562379"
//        }, {
//            "_index": "goods",
//                    "_id": "605616"
//        }, {
//            "_index": "goods",
//                    "_id": "635906"
//        }]
//        }

        List<Long> asList = Arrays.asList(536563L, 562379L, 605616L, 635906L);
        Iterable<Goods> list = goodsEsRepository.findAllById(asList);
        for (Goods item : list) {
            System.out.println(item);
        }
    }

    /**
     * 统计数量
     */
    @Test
    public void count() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {"from":0,"size":0}
        System.out.println(goodsEsRepository.count());
    }

    /**
     * 根据编号判断文档是否存在
     */
    @Test
    public void existsById() {
//         GET /goods/_doc/536563?_source=false
        System.out.println(goodsEsRepository.existsById(536563L));
    }

    /**
     * 删除文档
     */
    @Test
    public void delete() {
//        DELETE /goods/_doc/1?timeout=1m
        goodsEsRepository.findById(1L).ifPresent(goods -> goodsEsRepository.delete(goods));
    }

    /**
     * 删除所有文档
     */
    @Test
    public void deleteAll() {
        goodsEsRepository.deleteAll();
    }

    /**
     * 根据编号批量删除文档
     */
    @Test
    public void deleteAllByIds() {

        goodsEsRepository.deleteAll(goodsEsRepository.findAllById(Arrays.asList(1L, 2L, 3L)));
    }

    /**
     * 根据编号删除文档
     */
    @Test
    public void deleteById() {
//        DELETE 'http://127.0.0.1:9200/goods/_doc/4?timeout=1m'
        goodsEsRepository.deleteById(4L);
    }
/*
    自定义方法:

    Spring Data 的另一个强大功能,是根据方法名称自动实现功能。比如:你的方法名叫做:findByTitle,那么它就知道你是根据title查询,然后自动帮你完成,无需写实现类。当然,方法名称要符合一定的约定:
https://www.cnblogs.com/tanghaorong/p/16365684.html


    /**
     * 自定义方法:根据标题查询
     */
    @Test
    public void findByTitle() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "query": {
//            "bool": {
//                "must": [{
//                    "query_string": {
//                        "query": "华为",
//                                "fields": ["title^1.0"]
//                    }
//                }]
//            }
//        }
//        }
        goodsEsRepository.findByTitle("华为").forEach(System.out::println);
    }

    /**
     * 自定义方法:根据价格区间查询
     */
    @Test
    public void findByPriceBetween() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "query": {
//            "bool": {
//                "must": [{
//                    "range": {
//                        "price": {
//                            "from": 3000,
//                                    "to": 5000,
//                                    "include_lower": true,
//                                    "include_upper": true,
//                                    "boost": 1.0
//                        }
//                    }
//                }]
//            }
//        }
//        }
        goodsEsRepository.findByPriceBetween(new BigDecimal("3000"), new BigDecimal("5000")).forEach(System.out::println);
    }




    /**
     * 精确查询(termQuery)
     */
    @Test
    public void termQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {"from":0,"size":10,"query":{"term":{"categoryName":{"value":"手机","boost":1.0}}},"version":true,"explain":false}

        //查询条件(词条查询:对应ES query里的term)
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("categoryName", "手机");
        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(termQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = searchHits.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        searchHits.getSearchHits().stream().map(SearchHit<Goods>::getContent).forEach(System.out::println);
    }

    /**
     * terms:多个查询内容在一个字段中进行查询
     */
    @Test
    public void termsQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {"from":0,"size":10,"query":{"terms":{"categoryName":["手机","平板电视"],"boost":1.0}},"version":true,"explain":false}

        //查询条件(词条查询:对应ES query里的terms)
        TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("categoryName", "手机", "平板电视");
        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(termsQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = searchHits.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        searchHits.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    @Test
    public void matchQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "match": {
//                "title": {
//                    "query": "Apple IPhone 白色",
//                            "operator": "AND",
//                            "analyzer": "ik_smart",
//                            "prefix_length": 0,
//                            "max_expansions": 50,
//                            "fuzzy_transpositions": true,
//                            "lenient": false,
//                            "zero_terms_query": "NONE",
//                            "auto_generate_synonyms_phrase_query": true,
//                            "boost": 1
//                }
//            }
//        },
//            "version": true,
//                "explain": false
//        }
//
        //查询条件(词条查询:对应ES query里的match)
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "Apple IPhone 白色").analyzer("ik_smart").operator(Operator.AND);

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(matchQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = search.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * match_all:查询全部。
     * 默认查询10条
     */
    @Test
    public void matchAllQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "match_all": {
//                "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false
//        }
        //查询条件(词条查询:对应ES query里的match)
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = search.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * match_phrase:短语查询,在match的基础上进一步查询词组,可以指定slop分词间隔。
     * 默认查询10条
     */
    @Test
    public void matchPhraseQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "match_phrase": {
//                "title": {
//                    "query": "华为",
//                            "slop": 0,
//                            "zero_terms_query": "NONE",
//                            "boost": 1
//                }
//            }
//        },
//            "version": true,
//                "explain": false
//        }

        //查询条件(词条查询:对应ES query里的match_all)
        MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("title", "华为");

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(matchPhraseQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = search.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * multi_match:多字段查询,使用相当的灵活,可以完成match_phrase和match_phrase_prefix的工作。
     */
    @Test
    public void multiMatchQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "multi_match": {
//                "query": "华为和Apple",
//                        "fields": [
//                "categoryName^1.0",
//                        "title^1.0"
//      ],
//                "type": "best_fields",
//                        "operator": "OR",
//                        "analyzer": "ik_smart",
//                        "slop": 0,
//                        "prefix_length": 0,
//                        "max_expansions": 50,
//                        "zero_terms_query": "NONE",
//                        "auto_generate_synonyms_phrase_query": true,
//                        "fuzzy_transpositions": true,
//                        "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false
//        }


        //查询条件(词条查询:对应ES query里的multi_match)
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("华为和Apple", "title", "categoryName").analyzer("ik_smart");

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(multiMatchQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = search.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }


    /**
     * 通配符查询
     * <p>
     * *:表示多个字符(0个或多个字符)
     * ?:表示单个字符
     */
    @Test
    public void wildcardQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "wildcard": {
//                "title": {
//                    "wildcard": "华为*",
//                            "boost": 1
//                }
//            }
//        },
//            "version": true,
//                "explain": false
//        }
        //查询条件
        WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery( "title","华为*");

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(wildcardQueryBuilder).build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        long totalHits = search.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * 排序查询(sort)
     * 匹配查询符合条件的所有数据,并设置分页
     */
    @Test
    public void sort() {
        //查询条件(词条查询:对应ES query里的match)
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "match_all": {
//                "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false,
//                "sort": [
//            {
//                "price": {
//                "order": "desc"
//            }
//            }
//  ]
//        }

        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("price").order(SortOrder.DESC);
        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchAllQueryBuilder)
                .withSorts(fieldSortBuilder)
                .build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);
        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * 分页查询(page)
     */
    @Test
    public void pageQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 5,
//                "query": {
//            "match_all": {
//                "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false,
//                "sort": [
//            {
//                "price": {
//                "order": "desc"
//            }
//            }
//  ]
//        }
        //查询条件
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("price").order(SortOrder.DESC);

        // 分页数据
        PageRequest pageRequest = PageRequest.of(0, 5);

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchAllQueryBuilder)
                .withSorts(fieldSortBuilder)
                .withPageable(pageRequest)
                .build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数,当前页,每页大小
        System.out.println("totalHits = " + search.getTotalHits());
        System.out.println("pageNumber = " + pageRequest.getPageNumber());
        System.out.println("pageSize = " + pageRequest.getPageSize());
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * 滚动查询所有数据
     */
    @Test
    public void scrollQuery1() {
        // 设置每页数据量
        int pageSize = 10;
        MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();//条件
        FieldSortBuilder sortBuilder = new FieldSortBuilder("id").order(SortOrder.ASC);//排序
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).withSorts(sortBuilder).build();
        nativeSearchQuery.setMaxResults(pageSize);// 设置每页数据量

        long scrollTimeInMillis = 60 * 1000;//设置缓存内数据的保留时间,不要把缓存时时间设置太长,否则占用内存。
        // 缓存第一页符合搜索条件的数据
        SearchScrollHits<Goods> searchScrollHits = elasticsearchRestTemplate.searchScrollStart(scrollTimeInMillis, nativeSearchQuery, Goods.class, IndexCoordinates.of("goods"));
        String scrollId = searchScrollHits.getScrollId();

        int scrollTime = 1;
        while (searchScrollHits.hasSearchHits()) {// 判断searchScrollHits中是否有命中数据,如果为空,则表示已将符合查询条件的数据全部遍历完毕
            System.out.println("第" + scrollTime + "页数据,数据总数:" + searchScrollHits.getSearchHits().size());

            for (SearchHit<Goods> searchHit : searchScrollHits.getSearchHits()) {// 从缓存中读取数据
                Goods goods = searchHit.getContent();
                System.out.println(goods);
            }
            // 根据上次搜索结果scroll_id进入下一页数据搜索
            searchScrollHits = elasticsearchRestTemplate.searchScrollContinue(scrollId, scrollTimeInMillis, Goods.class, IndexCoordinates.of("goods"));//该方法执行后将重新刷新快照保留时间
            scrollId = searchScrollHits.getScrollId();
            scrollTime = scrollTime + 1;
        }

        List<String> scrollIds = new ArrayList<>();
        scrollIds.add(scrollId);

//        DELETE 'http://127.0.0.1:9200/_search/scroll' -d '{"scroll_id":["FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFnZndHRsM0lsU3VPQ0dLQnVwY0V4UlEAAAAAAAAJXhZ4MTI3QUpXYVEtbWtjVU1WQ0d6S1Vn"]}'
        elasticsearchRestTemplate.searchScrollClear(scrollIds);// 清除 scroll
    }


    /**
     * 根据查询条件滚动查询
     * 可以用来解决深度分页查询问题
     */
    @Test
    public void scrollQuery2() {

        // 假设用户想获取第70页数据,其中每页10条
        int pageNo = 70;
        int pageSize = 10;

        // 构建查询条件
        MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        FieldSortBuilder sortBuilder = new FieldSortBuilder("id").order(SortOrder.ASC);//排序
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withSorts(sortBuilder)
                .build();
        nativeSearchQuery.setMaxResults(pageSize);// 设置每页数据量

        long scrollTimeInMillis = 60 * 1000;//设置缓存内数据的保留时间
        //1、缓存第一页符合搜索条件的数据
//        GET /goods/_search?scroll=60000ms&typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "match_all": {
//                "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false,
//                "sort": [
//            {
//                "id": {
//                "order": "asc"
//            }
//            }
//  ]
//        }
        SearchScrollHits<Goods> searchScrollHits = elasticsearchRestTemplate.searchScrollStart(scrollTimeInMillis, nativeSearchQuery, Goods.class, IndexCoordinates.of("goods"));
        String scrollId = searchScrollHits.getScrollId();
        int scrollTime = 1;
        // 判断searchScrollHits中是否有命中数据,如果为空,则表示已将符合查询条件的数据全部遍历完毕
        while (searchScrollHits.hasSearchHits() && scrollTime < pageNo) {
            // 根据上次搜索结果scroll_id进入下一页数据搜索
//            POST /_search/scroll
//            {
//                "scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFnZndHRsM0lsU3VPQ0dLQnVwY0V4UlEAAAAAAAASqhZ4MTI3QUpXYVEtbWtjVU1WQ0d6S1Vn",
//                    "scroll": "60000ms"
//            }

            searchScrollHits = elasticsearchRestTemplate.searchScrollContinue(scrollId, scrollTimeInMillis, Goods.class, IndexCoordinates.of("goods"));//该方法执行后会重新刷新快照保留时间
            scrollId = searchScrollHits.getScrollId();
            scrollTime = scrollTime + 1;
        }

        List<String> scrollIds = new ArrayList<>();
        scrollIds.add(scrollId);

        // 清除 scroll
//        DELETE /_search/scroll
//        {
//            "scroll_id": [
//            "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFnZndHRsM0lsU3VPQ0dLQnVwY0V4UlEAAAAAAAAgiBZ4MTI3QUpXYVEtbWtjVU1WQ0d6S1Vn"
//  ]
//        }
//        成功时返回
//        {
//            "succeeded" : true,
//                "num_freed" : 1
//        }

        elasticsearchRestTemplate.searchScrollClear(scrollIds);

        //4、 从缓存中读取数据
        for (SearchHit<Goods> searchHit : searchScrollHits.getSearchHits()) {
            Goods goods = searchHit.getContent();
            System.out.println(goods);
        }
    }


    /**
     * 范围查询(range)
     */
    @Test
    public void range() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "range": {
//                "price": {
//                    "from": 1000,
//                            "to": 2000,
//                            "include_lower": true,
//                            "include_upper": true,
//                            "boost": 1
//                }
//            }
//        },
//            "version": true,
//                "explain": false
//        }

        //查询条件
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").from(1000).to(2000);

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(rangeQueryBuilder)
                .build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }


    /**
     * boolQuery 查询
     */
    @Test
    public void boolQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "bool": {
//                "must": [
//                {
//                    "match": {
//                    "title": {
//                        "query": "金立",
//                                "operator": "OR",
//                                "prefix_length": 0,
//                                "max_expansions": 50,
//                                "fuzzy_transpositions": true,
//                                "lenient": false,
//                                "zero_terms_query": "NONE",
//                                "auto_generate_synonyms_phrase_query": true,
//                                "boost": 1
//                    }
//                }
//                },
//                {
//                    "match": {
//                    "categoryName": {
//                        "query": "手机",
//                                "operator": "OR",
//                                "prefix_length": 0,
//                                "max_expansions": 50,
//                                "fuzzy_transpositions": true,
//                                "lenient": false,
//                                "zero_terms_query": "NONE",
//                                "auto_generate_synonyms_phrase_query": true,
//                                "boost": 1
//                    }
//                }
//                }
//      ],
//                "filter": [
//                {
//                    "range": {
//                    "price": {
//                        "from": 1000,
//                                "to": 2000,
//                                "include_lower": false,
//                                "include_upper": false,
//                                "boost": 1
//                    }
//                }
//                }
//      ],
//                "adjust_pure_negative": true,
//                        "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false
//        }


        //查询条件(词条查询:对应ES query里的match)
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("title", "金立"))
                .must(QueryBuilders.matchQuery("categoryName", "手机"))
                .filter(QueryBuilders.rangeQuery("price").gt(1000).lt(2000));

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }


    /**
     * queryStringQuery查询
     * 案例:查询出必须包含 华为手机 词语的商品信息
     */
    @Test
    public void queryStringQuery() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "query_string": {
//                "query": "华为手机",
//                        "fields": [],
//                "type": "best_fields",
//                        "default_operator": "and",
//                        "max_determinized_states": 10000,
//                        "enable_position_increments": true,
//                        "fuzziness": "AUTO",
//                        "fuzzy_prefix_length": 0,
//                        "fuzzy_max_expansions": 50,
//                        "phrase_slop": 0,
//                        "escape": false,
//                        "auto_generate_synonyms_phrase_query": true,
//                        "fuzzy_transpositions": true,
//                        "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false
//        }

        // 创建 queryString 查询构建器
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("华为手机").defaultOperator(Operator.AND);

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryStringQueryBuilder)
                .build();

        // 执行查询,然后处理响应结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * 过滤source获取部分字段内容
     */
    @Test
    public void sourceFilter() {
        //查询条件(词条查询:对应ES query里的match)
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("title", "金立"))
                .must(QueryBuilders.matchQuery("categoryName", "手机"))
                .filter(QueryBuilders.rangeQuery("price").gt(1000).lt(2000));
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "bool": {
//                "must": [
//                {
//                    "match": {
//                    "title": {
//                        "query": "金立",
//                                "operator": "OR",
//                                "prefix_length": 0,
//                                "max_expansions": 50,
//                                "fuzzy_transpositions": true,
//                                "lenient": false,
//                                "zero_terms_query": "NONE",
//                                "auto_generate_synonyms_phrase_query": true,
//                                "boost": 1
//                    }
//                }
//                },
//                {
//                    "match": {
//                    "categoryName": {
//                        "query": "手机",
//                                "operator": "OR",
//                                "prefix_length": 0,
//                                "max_expansions": 50,
//                                "fuzzy_transpositions": true,
//                                "lenient": false,
//                                "zero_terms_query": "NONE",
//                                "auto_generate_synonyms_phrase_query": true,
//                                "boost": 1
//                    }
//                }
//                }
//      ],
//                "filter": [
//                {
//                    "range": {
//                    "price": {
//                        "from": 1000,
//                                "to": 2000,
//                                "include_lower": false,
//                                "include_upper": false,
//                                "boost": 1
//                    }
//                }
//                }
//      ],
//                "adjust_pure_negative": true,
//                        "boost": 1
//            }
//        },
//            "version": true,
//                "explain": false,
//                "_source": {
//            "includes": [
//            "title",
//                    "categoryName"
//    ],
//            "excludes": []
//        }
//        }


        // 不需要获取source结果集
        SourceFilter sourceFilter = new FetchSourceFilterBuilder().withIncludes("title", "categoryName").build();

        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withSourceFilter(sourceFilter)
                .build();
        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回
        search.getSearchHits().stream().map(SearchHit::getContent).forEach(System.out::println);
    }

    /**
     * 高亮查询
     */
    @Test
    public void highlightBuilder() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "query": {
//            "match": {
//                "title": {
//                    "query": "三星手机",
//                            "operator": "OR",
//                            "prefix_length": 0,
//                            "max_expansions": 50,
//                            "fuzzy_transpositions": true,
//                            "lenient": false,
//                            "zero_terms_query": "NONE",
//                            "auto_generate_synonyms_phrase_query": true,
//                            "boost": 1
//                }
//            }
//        },
//            "version": true,
//                "explain": false,
//                "highlight": {
//            "pre_tags": [
//            "<font color='red'>"
//    ],
//            "post_tags": [
//            "</font>"
//    ],
//            "fields": {
//                "title": {}
//            }
//        }
//        }

        //查询条件(词条查询:对应ES query里的match)
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "三星手机");

        //设置高亮三要素                                    field: 你的高亮字段    // preTags :前缀    // postTags:后缀
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("title").preTags("<font color='red'>").postTags("</font>");
        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchQueryBuilder)
                .withHighlightBuilder(highlightBuilder)
                .build();

        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回

        search.getSearchHits().stream().map(searchHit -> {
            //获得结果实体
            Goods goods = searchHit.getContent();
            //所有高亮结果
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            //遍历高亮结果
            for (Map.Entry<String, List<String>> stringListEntry : highlightFields.entrySet()) {
                String key = stringListEntry.getKey();
                //获取实体反射类
                Class<?> aClass = goods.getClass();
                try {
                    //获取该实体属性
                    Field declaredField = aClass.getDeclaredField(key);
                    //权限为私的 解除!
                    declaredField.setAccessible(true);
                    //替换,把高亮字段替换到这个实体对应的属性值上
                    declaredField.set(goods, stringListEntry.getValue().get(0));
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            return goods;
        }).forEach(System.out::println);
    }

    /**
     * 案例:分别获取最贵的商品和获取最便宜的商品
     */
    @Test
    public void aggMetric() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "version": true,
//                "explain": false,
//                "_source": {
//            "includes": [],
//            "excludes": []
//        },
//            "aggregations": {
//            "maxPrice": {
//                "max": {
//                    "field": "price"
//                }
//            },
//            "minPrice": {
//                "min": {
//                    "field": "price"
//                }
//            }
//        }
//        }



        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 聚合条件
        queryBuilder.withAggregations(AggregationBuilders.max("maxPrice").field("price")
                ,AggregationBuilders.min("minPrice").field("price"));

//        queryBuilder.addAggregation(AggregationBuilders.max("maxPrice").field("price"));
//        queryBuilder.addAggregation(AggregationBuilders.min("minPrice").field("price"));

        queryBuilder.withSourceFilter(new FetchSourceFilterBuilder().build());
        //查询,获取查询结果
        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Goods.class, IndexCoordinates.of("goods"));
        //获取聚合结果
        Aggregations aggregations = (Aggregations)searchHits.getAggregations().aggregations();
        assert aggregations != null;
        //打印聚合结果
        ParsedMax max = aggregations.get("maxPrice");
        System.out.println("最贵的价格:" + max.getValue());
        ParsedMin min = aggregations.get("minPrice");
        System.out.println("最便宜的价格:" + min.getValue());
    }


    /**
     * 根据商品分类聚合查询
     */
    @Test
    public void aggBucket() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "version": true,
//                "explain": false,
//                "_source": {
//            "includes": [],
//            "excludes": []
//        },
//            "aggregations": {
//            "aggCategoryName": {
//                "terms": {
//                    "field": "categoryName",
//                            "size": 10,
//                            "min_doc_count": 1,
//                            "shard_min_doc_count": 0,
//                            "show_term_doc_count_error": false,
//                            "order": [
//                    {
//                        "_count": "desc"
//                    },
//                    {
//                        "_key": "asc"
//                    }
//        ]
//                }
//            }
//        }
//        }
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 聚合条件
        queryBuilder.withAggregations(AggregationBuilders.terms("aggCategoryName").field("categoryName").size(10));
        queryBuilder.withSourceFilter(new FetchSourceFilterBuilder().build());
        //查询,获取查询结果
        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Goods.class, IndexCoordinates.of("goods"));
        //获取聚合结果
//        Aggregations aggregations = searchHits.getAggregations();
//        assert aggregations != null;
//        ParsedStringTerms aggCategoryName = aggregations.get("aggCategoryName");
//        //打印聚合结果
//        System.out.println(aggCategoryName.getBuckets());
//        for (Terms.Bucket bucket : aggCategoryName.getBuckets()) {
//            System.out.println(bucket.getKeyAsString() + "====" + bucket.getDocCount());
//
//        }
        System.out.println(searchHits.getAggregations());
    }

    /**
     * 根据价格区间分组查询
     */
    @Test
    public void aggRange() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "version": true,
//                "explain": false,
//                "_source": {
//            "includes": [],
//            "excludes": []
//        },
//            "aggregations": {
//            "priceRange": {
//                "range": {
//                    "field": "price",
//                            "ranges": [
//                    {
//                        "to": 1000
//                    },
//                    {
//                        "from": 1000,
//                            "to": 3000
//                    },
//                    {
//                        "from": 3000
//                    }
//        ],
//                    "keyed": false
//                }
//            }
//        }
//        }

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        queryBuilder.withAggregations(AggregationBuilders.range("priceRange").field("price").addUnboundedTo(1000).addRange(1000, 3000).addUnboundedFrom(3000));
        queryBuilder.withSourceFilter(new FetchSourceFilterBuilder().build());

        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Goods.class, IndexCoordinates.of("goods"));

        // 获取聚合信息
        Aggregations aggregations =(Aggregations) searchHits.getAggregations().aggregations();
        assert aggregations != null;
        ParsedRange priceRange = aggregations.get("priceRange");

        //获取总记录数
        System.out.println("totalHits = " + searchHits.getTotalHits());

        //获取值返回
        for (Range.Bucket bucket : priceRange.getBuckets()) {
            System.out.println(bucket.getKeyAsString() + "====" + bucket.getDocCount());
        }

    }

    /**
     * 根据日期分组查询出商品创建日期在"2017-09" - "2017-10" 之间的数据
     */
    @Test
    public void aggDateRange() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "version": true,
//                "explain": false,
//                "_source": {
//            "includes": [],
//            "excludes": []
//        },
//            "aggregations": {
//            "dateRange": {
//                "date_range": {
//                    "field": "createTime",
//                            "format": "yyy-MM",
//                            "ranges": [
//                    {
//                        "from": "2017-09",
//                            "to": "2017-10"
//                    }
//        ],
//                    "keyed": false
//                }
//            }
//        }
//        }

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // range查询包左不包右,即:[1,10)
        queryBuilder.withAggregations(AggregationBuilders.dateRange("dateRange").field("createTime").format("yyy-MM").addRange("2017-09", "2017-10"));
        queryBuilder.withSourceFilter(new FetchSourceFilterBuilder().build());

        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Goods.class, IndexCoordinates.of("goods"));

        // 获取聚合信息
        Aggregations aggregations = (Aggregations)searchHits.getAggregations().aggregations();
        assert aggregations != null;
        ParsedDateRange priceRange = aggregations.get("dateRange");

        //获取总记录数
        System.out.println("totalHits = " + searchHits.getTotalHits());

        //获取值返回
        for (Range.Bucket bucket : priceRange.getBuckets()) {
            System.out.println(bucket.getKeyAsString() + "====" + bucket.getDocCount());
        }
    }


    /**
     * 根据品牌聚合获取出每个品牌的平均价格
     */
    @Test
    public void subAgg() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "version": true,
//                "explain": false,
//                "aggregations": {
//            "brandNameAgg": {
//                "terms": {
//                    "field": "brandName",
//                            "size": 10,
//                            "min_doc_count": 1,
//                            "shard_min_doc_count": 0,
//                            "show_term_doc_count_error": false,
//                            "order": [
//                    {
//                        "_count": "desc"
//                    },
//                    {
//                        "_key": "asc"
//                    }
//        ]
//                },
//                "aggregations": {
//                    "avgPrice": {
//                        "avg": {
//                            "field": "price"
//                        }
//                    }
//                }
//            }
//        }
//        }


        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        queryBuilder.withAggregations(AggregationBuilders.terms("brandNameAgg").field("brandName")
                .subAggregation(AggregationBuilders.avg("avgPrice").field("price")));

        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Goods.class, IndexCoordinates.of("goods"));

        // 获取聚合信息
        Aggregations aggregations = (Aggregations)searchHits.getAggregations().aggregations();
        assert aggregations != null;
        ParsedStringTerms brandeNameAgg = aggregations.get("brandNameAgg");

        //获取总记录数
        System.out.println("totalHits = " + searchHits.getTotalHits());

        //获取值返回
        for (Terms.Bucket bucket : brandeNameAgg.getBuckets()) {

            // 获取聚合后的品牌名称
            String brandName = bucket.getKeyAsString();
            // 获取聚合命中的文档数量
            long docCount = bucket.getDocCount();
            // 获取聚合后的品牌的平均价格,注意返回值不是Aggregation对象,而是指定的ParsedAvg对象
            ParsedAvg avgPrice = bucket.getAggregations().get("avgPrice");

            System.out.println(brandName + "======" + avgPrice.getValue() + "======" + docCount);
        }


    }

    /**
     * 根据商品分类聚合,获取每个商品类的平均价格,并且在商品分类聚合之上子聚合每个品牌的平均价格
     */
    @Test
    public void subSubAgg() {
//        GET /goods/_search?typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512
//        {
//            "from": 0,
//                "size": 10,
//                "version": true,
//                "explain": false,
//                "aggregations": {
//            "categoryNameAgg": {
//                "terms": {
//                    "field": "categoryName",
//                            "size": 10,
//                            "min_doc_count": 1,
//                            "shard_min_doc_count": 0,
//                            "show_term_doc_count_error": false,
//                            "order": [
//                    {
//                        "_count": "desc"
//                    },
//                    {
//                        "_key": "asc"
//                    }
//        ]
//                },
//                "aggregations": {
//                    "categoryNameAvgPrice": {
//                        "avg": {
//                            "field": "price"
//                        }
//                    },
//                    "brandNameAgg": {
//                        "terms": {
//                            "field": "brandName",
//                                    "size": 10,
//                                    "min_doc_count": 1,
//                                    "shard_min_doc_count": 0,
//                                    "show_term_doc_count_error": false,
//                                    "order": [
//                            {
//                                "_count": "desc"
//                            },
//                            {
//                                "_key": "asc"
//                            }
//            ]
//                        },
//                        "aggregations": {
//                            "brandNameAvgPrice": {
//                                "avg": {
//                                    "field": "price"
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        }

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // 注意这里聚合写的位置不要写错,很容易搞混,错一个括号就不对了
        queryBuilder.withAggregations(
                AggregationBuilders.terms("categoryNameAgg").field("categoryName")
                        .subAggregation(AggregationBuilders.avg("categoryNameAvgPrice").field("price"))
                        .subAggregation(AggregationBuilders.terms("brandNameAgg").field("brandName")
                                .subAggregation(AggregationBuilders.avg("brandNameAvgPrice").field("price"))));

        SearchHits<Goods> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Goods.class, IndexCoordinates.of("goods"));

        // 获取聚合信息
        Aggregations aggregations = (Aggregations)searchHits.getAggregations().aggregations();
        assert aggregations != null;
        ParsedStringTerms categoryNameAgg = aggregations.get("categoryNameAgg");

        //获取总记录数
        System.out.println("totalHits = " + searchHits.getTotalHits());

        //获取值返回
        for (Terms.Bucket bucket : categoryNameAgg.getBuckets()) {

            // 获取聚合后的分类名称
            String categoryName = bucket.getKeyAsString();
            // 获取聚合命中的文档数量
            long docCount = bucket.getDocCount();
            // 获取聚合后的分类的平均价格,注意返回值不是Aggregation对象,而是指定的ParsedAvg对象
            ParsedAvg avgPrice = bucket.getAggregations().get("categoryNameAvgPrice");

            System.out.println(categoryName + "======" + avgPrice.getValue() + "======" + docCount);

            ParsedStringTerms brandNameAgg = bucket.getAggregations().get("brandNameAgg");
            for (Terms.Bucket brandeNameAggBucket : brandNameAgg.getBuckets()) {
                // 获取聚合后的品牌名称
                String brandName = brandeNameAggBucket.getKeyAsString();

                // 获取聚合后的品牌的平均价格,注意返回值不是Aggregation对象,而是指定的ParsedAvg对象
                ParsedAvg brandNameAvgPrice = brandeNameAggBucket.getAggregations().get("brandNameAvgPrice");

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




}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值