当前位置: 代码网 > it编程>编程语言>Java > 【ES常用查询】基于ElasticsearchRestTemplate及NativeSearchQuery的查询

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

2024年08月01日 Java 我要评论
但是目前这边同事是基于estamplet跟nativeSearch做的。以前我们是基于高标准客户端直接做的,包含当前es所有的查询,

包含当前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 {

  //聚合2
    //参加聚合的字段必须是keyword、日期、数值、布尔类型
    @postmapping("/es/agg2")
    public void agg2() throws ioexception {

        // 1.创建request对象
        searchrequest request = new searchrequest("298_ops-web-js_1");
        // 2.准备请求的参数:dsl语句
        request.source().size(0);
        //参数一:聚合查询的名字  参数二:根据appid做分组   参数三:最多显示10条
      //  termsaggregationbuilder aggregationbuilder = aggregationbuilders.max("bsversionagg").field("appid");
        maxaggregationbuilder maxaggs = aggregationbuilders.max("score").field("bsversion");
        request.source().aggregation(
                maxaggs
        );

        try {
            searchresponse response = client.search(request, requestoptions.default);
            aggregations aggregations = response.getaggregations();
            terms bsversionagg = aggregations.get("bsversionagg");
            list<? extends terms.bucket> buckets = bsversionagg.getbuckets();
            for (terms.bucket bucket : buckets) {
                string key = bucket.getkeyasstring();
                //getdoccount:该桶下的文档总数
                long doccount = bucket.getdoccount();
                log.info("key:{},doccount:{}", key, doccount);
            }
        } catch (ioexception e) {
            log.error("es查询异常:{}", e.getmessage());
        }

    }



    //聚合
    //参加聚合的字段必须是keyword、日期、数值、布尔类型
    @postmapping("/es/agg")
    public void agg() {
        // 1.创建request对象
        searchrequest request = new searchrequest("298_ops-web-js_1");
        // 2.准备请求的参数:dsl语句
        request.source().size(0);
        //参数一:聚合查询的名字  参数二:根据appid做分组   参数三:最多显示10条
        termsaggregationbuilder aggregationbuilder = aggregationbuilders.terms("bsversionagg").field("appid").size(5);

        request.source().aggregation(
                aggregationbuilder
        );

        try {
            searchresponse response = client.search(request, requestoptions.default);
            aggregations aggregations = response.getaggregations();
            terms bsversionagg = aggregations.get("bsversionagg");
            list<? extends terms.bucket> buckets = bsversionagg.getbuckets();
            for (terms.bucket bucket : buckets) {
                string key = bucket.getkeyasstring();
                //getdoccount:该桶下的文档总数
                long doccount = bucket.getdoccount();
                log.info("key:{},doccount:{}", key, doccount);
            }
        } catch (ioexception e) {
            log.error("es查询异常:{}", e.getmessage());
        }
    }


    /************************************************************************
     ————————————————————————————以下为不携带聚合的查询————————————————————————————————————————————
     ************************************************************************/



    /**
     * 测试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());
        }
    }


}

————————————————————————————————————

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com