Elasticsearch 7.17.6 windows环境下学习

下载地址

Elasticsearch 7.17.6
Kibana 7.17.6

ES 配置

配置ES的JDK11,指向解压包
ES_JAVA_HOME
Elasticsearch 7.17.6 windows环境下学习_第1张图片

修改ES启动的运存

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

-Xms128m
-Xmx512m

Elasticsearch 7.17.6 windows环境下学习_第2张图片

启动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 文件。
Elasticsearch 7.17.6 windows环境下学习_第3张图片
3.重启ES服务
4.智能分词里就有自己添加的词
Elasticsearch 7.17.6 windows环境下学习_第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);
    }


    /**
     * 通配符查询
     * 

* *:表示多个字符(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": [ // "" // ], // "post_tags": [ // "" // ], // "fields": { // "title": {} // } // } // } //查询条件(词条查询:对应ES query里的match) MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "三星手机"); //设置高亮三要素 field: 你的高亮字段 // preTags :前缀 // postTags:后缀 HighlightBuilder highlightBuilder = new HighlightBuilder().field("title").preTags("").postTags(""); //创建查询条件构建器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()); } } } }

你可能感兴趣的:(elasticsearch,学习,java)