【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());
        }
    }


}

相关推荐
枫叶丹41 小时前
【在Linux世界中追寻伟大的One Piece】进程信号
linux·运维·服务器
刻词梨木1 小时前
ubuntu中挂载点内存不足,分配不合理后使用软链接的注意事项
linux·运维·ubuntu
灯火不休ᝰ2 小时前
[win7] win7系统的下载及在虚拟机中详细安装过程(附有下载文件)
linux·运维·服务器
HHoao5 小时前
Ubuntu启动后第一次需要很久才能启动GTK应用问题
linux·运维·ubuntu
小灰兔的小白兔5 小时前
【Ubuntu】Ubuntu常用命令
linux·运维·ubuntu
winds~5 小时前
ubuntu中软件的进程管理-结束软件运行
linux·运维·ubuntu
bush46 小时前
使用root账号ssh登录虚拟机ubuntu
运维·ubuntu·ssh
叫我龙翔7 小时前
【Linux】进程间关系与守护进程
linux·运维·服务器·计算机网络
S hh7 小时前
【Linux】进程地址空间
java·linux·运维·服务器·学习
苹果醋38 小时前
大模型实战--FastChat一行代码实现部署和各个组件详解
java·运维·spring boot·mysql·nginx