【ES常用查询】基于ElasticsearchRestTemplate及NativeSearchQuery的查询

包含当前es所有的查询,

需要什么代码直接照搬,改个参数就行!

用的好请务必给我点赞!!!感谢爱你们!!!

(周末更 筒)

为啥写这篇文章呢:

大概是因为目前公司用的api跟以前的不太一样,

以前我们是基于高标准客户端直接做的,

但是目前这边同事是基于ElasticsearchRestTemplate跟NativeSearchQuery做的。

复制代码
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/v/k/t/query")
public class EsTestController {
    /**
     * 测试es各种查询方法*
     */

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    //通配符查询
    @PostMapping("/es/wildcard")
    public void wildcard() {
        //*:匹配任意数量的字符(包括零个字符)。 *x*: 对x做前后N位做模糊查询,前后有多少值都可以查到(也可以左模糊或者右模糊)
        //?:用于匹配单个字符.    user?a: user?a   匹配user1a,但不匹配user123a
        //^:必须以某个字符开头,如^user*:必须以user开头
        //$:必须以某个字符结尾,如user$:必须以user结尾

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //wildcardQuery:通配符查询
        WildcardQueryBuilder bsVersion = QueryBuilders.wildcardQuery("bsVersion", "*1*");
        WildcardQueryBuilder bsVersion2 = QueryBuilders.wildcardQuery("type", "*j*");
        boolQueryBuilder.must(bsVersion).should(bsVersion2);

        NativeSearchQuery dsl = new NativeSearchQueryBuilder()
    }

    //高亮
    //默认情况下:只能对查询字段高亮!!!
    //加了.requireFieldMatch(false) 可以对非查询字段高亮,具体看下文
    @PostMapping("/es/highlight")
    public void highlight() {

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //wildcardQuery:通配符查询
        WildcardQueryBuilder bsVersion = QueryBuilders.wildcardQuery("bsVersion", "*1*");
        WildcardQueryBuilder bsVersion2 = QueryBuilders.wildcardQuery("type", "*j*");
        boolQueryBuilder.must(bsVersion).should(bsVersion2);

        NativeSearchQuery dsl = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightFields(
                        //.requireFieldMatch(false) : 加了可以对非查询字段高亮
                        new HighlightBuilder.Field("bsVersion").preTags("<em>").postTags("</em>").requireFieldMatch(false),
                        new HighlightBuilder.Field("provinceNameCn").preTags("<em>").postTags("</em>").requireFieldMatch(false),
                        new HighlightBuilder.Field("isp").preTags("<em>").postTags("</em>").requireFieldMatch(false),
                        new HighlightBuilder.Field("type").preTags("<em>").postTags("</em>").requireFieldMatch(false),
                        new HighlightBuilder.Field("agentId").preTags("<em>").postTags("</em>").requireFieldMatch(false)
                )
                .build();

        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            // 高亮字段是个大MAP  高亮字段集合 = {bsVersion=[<em>115</em>]}  //K=字段名 V=高亮了的数据集合
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            System.out.println("获取高亮字段集合:bsVersion =  " + highlightFields.get("bsVersion"));
            System.out.println("获取高亮字段集合:provinceNameCn =  " + highlightFields.get("provinceNameCn"));
            System.out.println("获取高亮字段集合:isp =  " + highlightFields.get("isp"));
            System.out.println("获取高亮字段集合:type =  " + highlightFields.get("type"));
            System.out.println("获取高亮字段集合:agentId =  " + highlightFields.get("agentId"));
            List<String> bsVersionResult = highlightFields.get("bsVersion");
            for (String s : bsVersionResult) {
                System.out.println("bsVersion集合每一个值为 = " + s);
            }

//            highlightFields.forEach((k, v) -> {
//                //获取高亮字段:k = bsVersion v = [<em>115</em>]
//                System.out.println("获取高亮字段:k = " + k + " v = " + v);
//            });
        }
        log.info("总条数:{}", search.getTotalHits());
        System.out.println("search.getSearchHits().size() = " + search.getSearchHits().size());
    }

    //排序
    @PostMapping("/es/sort")
    public void sort() {
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

        //备注:这里用的是NativeSearchQueryBuilder:xxxBuilder。最后一定要.build();,不然条件用不了
        NativeSearchQuery dsl = new NativeSearchQueryBuilder()
                .withQuery(matchAllQuery)
                //备注:应该是要keyword,paasword这一类才能排序。我用text类型排序报:非法字段异常
                .withSorts(SortBuilders.fieldSort("appId").order(SortOrder.ASC)) //排序:根据bsVersion升序排序
                .build();

        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }

    }

    //分页
    @PostMapping("/es/page")
    public void page() {
        Integer page = 1;
        Integer size = 10;
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        NativeSearchQuery dsl = new NativeSearchQuery(matchAllQuery);
        //分页
        Pageable pageable = PageRequest.of((page - 1) * size, size);
        dsl.setPageable(pageable);

        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());

        // 获取当前页数
        log.info("当前页数:{}", page);

        // 获取当前页的条数
        int currentSize = search.getSearchHits().size();
        log.info("当前页条数:{}", currentSize);

        //数据列表:search.getSearchHits()  for出每一条,然后加到list中

        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }

    }


    //布尔查询
    @PostMapping("/es/boolQueryBuilder")
    public void boolQueryBuilder() {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //must 必须满足且参与算分
        boolQueryBuilder.must(QueryBuilders.matchQuery("bsVersion", "114"));
        //mustNot 必须不满足   appID 300-700之间不参与查询(就是直接筛掉了)
        boolQueryBuilder.mustNot(QueryBuilders.rangeQuery("appId").gte("300").lte("700"));
        //filter 必须满足,且不参与算分
//        boolQueryBuilder.filter(QueryBuilders.termQuery("agentId", "298_ead348abbaf30f48"));
        NativeSearchQuery dsl = new NativeSearchQuery(boolQueryBuilder);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }
    }


    //算分函数查询
    @PostMapping("/es/FunctionScoreQueryBuilder")
    public void FunctionScoreQueryBuilder() {
        FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
                //原始查询
                QueryBuilders.matchAllQuery(),
                //算分数组
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        //第一个元素
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                //过滤器
                                QueryBuilders.matchQuery("bsVersion", "114"),
                                //权重
                                ScoreFunctionBuilders.weightFactorFunction(10)
                        ),
                        //第二个元素
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                //过滤器
                                QueryBuilders.matchQuery("bsVersion", "115"),
                                //权重
                                ScoreFunctionBuilders.weightFactorFunction(10)
                        )
                }).boostMode(CombineFunction.REPLACE);

        NativeSearchQuery dsl = new NativeSearchQuery(functionScoreQueryBuilder);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }
    }

    //范围查询
    @PostMapping("/es/rangeQuery")
    public void rangeQuery() {
        //范围查询 appId字段  >=0   <=200   的数据
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("appId").gte("0").lte("200");
        NativeSearchQuery dsl = new NativeSearchQuery(rangeQueryBuilder);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }
    }

    //精确查询
    @PostMapping("/es/termQuery")
    public void termQuery() {
        //根据isp字段 精确查询 内网IP
        TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("isp", " 内网IP ");
        NativeSearchQuery dsl = new NativeSearchQuery(termsQueryBuilder);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }
    }


    //多字段查询
    @PostMapping("/es/multiMatchQuery")
    public void multiMatchQuery() {
        //备注:字段必须是text类型,可以分词类型!!!!
        //查找keyword、数值、日期、boolean等会报错!!!
        //如果放入精确类型的字段,会报错!!!!
        MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("114", "bsVersion", "type");//查询114根据"bsVersion","type"
        NativeSearchQuery dsl = new NativeSearchQuery(multiMatchQuery);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }
    }

    //单字段查询
    @PostMapping("/es/matchQuery")
    public void matchQuery() {
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("bsVersion", "114");
        NativeSearchQuery dsl = new NativeSearchQuery(matchQuery);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
            System.out.println("单条文档的id = " + searchHit.getId());
            System.out.println("单条文档的评分 = " + searchHit.getScore());
            System.out.println("单条文档索引名(表名) = " + searchHit.getIndex());//298_ops-web-js_1就是你输入的索引库名
        }
    }

    //查询所有
    @PostMapping("/es/matchAllQuery")
    public void matchAllQuery() {
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        NativeSearchQuery dsl = new NativeSearchQuery(matchAllQuery);
        SearchHits<Map> search = elasticsearchRestTemplate.search(dsl, Map.class, IndexCoordinates.of("298_ops-web-js_1"));
        log.info("总条数:{}", search.getTotalHits());
        log.info("查询原始对象:{}", search.getSearchHits());
        log.info("分数值:{}", search.getMaxScore());
        log.info("有无聚合:{}", search.hasAggregations());
        log.info("返回搜索命中数量的关系,例如精确值、估计值:{}", search.getTotalHitsRelation());
        log.info("判断是否存在搜索命中结果:{}", search.hasSearchHits());
        //原始结果的每一条数据
        for (SearchHit<Map> searchHit : search.getSearchHits()) {
            System.out.println("单条文档 = " + searchHit);
            System.out.println("单条文档的原数据 = " + searchHit.getContent());
        }
    }


}

相关推荐
荣--8 小时前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森9 小时前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜1 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB2 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode3 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220704 天前
如何搭建本地yum源(上)
运维
大树887 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠7 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质7 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工7 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信