实战中关于elasticsearch中的查询方法--高级查询

这篇具有很好参考价值的文章主要介绍了实战中关于elasticsearch中的查询方法--高级查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

因为最近要从elasticsearch中获取数据给前端展示,然后自己摸索到了一些查询方法,记录一下,以防忘记

只展示业务层的代码逻辑:

一、一次普通的查询方法:

 public ResultVO<List<PageVO<PageVulVo>>> page(PageParam param, @ResTypeValue String[] resTypeValues) {
        //排序
        if (StringUtils.isEmpty(param.getSortParams())) {
            param.setSortParams("first_time desc");
        }
        String sortParams = param.getSortParams();
        //搜索字段
//        Map<String, Object> map = ParamUtils.getMapBySearch(param);
        List<SearchParam> searchParams = param.getSearchParams();
        //查询条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        this.queryVul(searchParams, nativeSearchQueryBuilder);
        //排序和分页
        PubUtils.sortAndPage(sortParams, nativeSearchQueryBuilder, param);
        //过滤
        nativeSearchQueryBuilder.withCollapseField("code");
        //查询
        Page<RealVul> pageResult = realVulRepository.search(nativeSearchQueryBuilder.build());
        //组装
        List<PageVulVo> pageVulVoList = pageResult.getContent().stream().map(e -> new PageVulVo(e)).collect(Collectors.toList());
        //返回
        return ResultUtils.pageOk(pageVulVoList, pageResult.getTotalElements());

    }

搜索条件方法:

  public NativeSearchQueryBuilder queryVul(List<SearchParam> searchParams, NativeSearchQueryBuilder nativeSearchQueryBuilder) {
        //查询条件
        BoolQueryBuilder mustQuery = QueryBuilders.boolQuery();

        for (SearchParam searchParam : searchParams) {
            String value = searchParam.getFieldValue();
            String name = searchParam.getFieldName();

            switch (name){
                case "vul_name":
                    mustQuery.must(QueryBuilders.wildcardQuery("vul_name", "*" + value + "*"));
                    break;
                case "cve_code":
                    mustQuery.must(QueryBuilders.matchQuery("cve_code", value));
                    break;
                case "port":
                    mustQuery.must(QueryBuilders.matchQuery("port",value));
                    break;
                case "scan_type":
                    mustQuery.must(QueryBuilders.matchQuery("scan_type",value));
                    break;
                case "create_time":
                    List<Long> createTime = DateUtils.parseStringToLong(value);
                    mustQuery.must(QueryBuilders.rangeQuery("create_time").gte(createTime.get(0)).lte(createTime.get(1)));
                    break;
                default:
                    break;
            }
        }
        nativeSearchQueryBuilder.withQuery(mustQuery);

        return nativeSearchQueryBuilder;
    }

分页和排序的方法:

 public static NativeSearchQueryBuilder sortAndPage(String sortParams, NativeSearchQueryBuilder nativeSearchQueryBuilder, PageParam param) {

        Pageable pageable = PageRequest.of(param.getCurrPage() - 1, param.getPageNums());
        nativeSearchQueryBuilder.withPageable(pageable);

        if (sortParams.toLowerCase().contains("desc")) {
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortParams.substring(0, sortParams.indexOf(" "))).order(SortOrder.DESC));
        } else {
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortParams.substring(0, sortParams.indexOf(" "))).order(SortOrder.ASC));
        }
        return nativeSearchQueryBuilder;
    }

这就是普通的查询办法。

二、带有统计和求最高级别的字段值

 例如要对整个elastcsearch中的数据进行统计分组和巧合的时候,上述的方法就不能满足要求了。

例如要算出以下这种数据

实战中关于elasticsearch中的查询方法--高级查询

 

第一列是求出最高级别,第二列是算出数量,第三和第四列是算出不同级别的数量。 

为了应对这种需求,所以新的方法:

因为用的多线程是线程池,所以要自己格外配置线程池。


    @Resource
    public ElasticsearchRestTemplate estTemplate;
    @Autowired
    public AsyncTaskExecutor asyncExecutor;



public ResultVO<List<PageVO<PageVulByIpVo>>> pageVulByIp(PageParam param, @ResTypeValue String[] resTypeValue) throws ExecutionException, InterruptedException {
        //查询条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = queryPreposition(param);
        //分组
        nativeSearchQueryBuilder.addAggregation(
                AggregationBuilders.terms("ip_group").field("ip").size(Integer.MAX_VALUE)
                        //风险等级
                        .subAggregation(AggregationBuilders.max("vul_severity_max").field("vul_severity"))
                        //ip名称
                        .subAggregation(AggregationBuilders.terms("ip_name").field("ip"))
                        //发现时间
                        .subAggregation(AggregationBuilders.max("create_time").field("create_time"))
                        //排序+分页
                        .subAggregation(new BucketSortPipelineAggregationBuilder("bucket_sort", null)
                                .from(param.getCurrPage()).size(param.getPageNums()))
        );
        nativeSearchQueryBuilder.addAggregation(
                //统计总数
                AggregationBuilders.terms("ip_count").field("ip").size(Integer.MAX_VALUE)
        );
        //获取分页中的ip集合
        List<String> keyList = new ArrayList<>();
        //储存风险等级
        HashMap<String, Integer> vulSeverityMap = new HashMap<>();
        //储存ip内容;顺序为:ip,create_time
        HashMap<String, String> ipContent = new HashMap<>();
        //查询结果
        AggregatedPage<RealVul> pageResult = estTemplate.queryForPage(nativeSearchQueryBuilder.build(), RealVul.class);
        //进行分组
        Terms stringTerms = (Terms) Objects.requireNonNull(pageResult.getAggregation("ip_group"));
        Terms ipCount = (Terms) Objects.requireNonNull(pageResult.getAggregation("ip_count"));
        //获取总数
        long total = Long.valueOf(ipCount.getBuckets().size());

        for (Terms.Bucket bucket : stringTerms.getBuckets()) {
            String ip = bucket.getKeyAsString();
            //获取风险等级
            Map<String, Aggregation> aggregationMap = bucket.getAggregations().asMap();
            double vulSeverity = ((ParsedMax) aggregationMap.get("vul_severity_max")).getValue();
            Integer value = Integer.valueOf((int) vulSeverity);
            //获取时间
            Aggregation time = aggregationMap.get("create_time");
            String createTimeString = ((ParsedMax) time).getValueAsString();
            //获取ip地址
            Terms ipName = (Terms) Objects.requireNonNull(aggregationMap.get("ip_name"));
            String ipString = ipName.getBuckets().get(0).getKeyAsString();
            ipContent.put(ip,ipString+"/"+createTimeString);
            vulSeverityMap.put(ip, value);
            //获取ip
            keyList.add(ip);
        }
        //获取当前用户所需的数据
        List<PageVulByIpVo> vulByIpVoList = new ArrayList<>();
        //资产相关的名称
        BaseVO<List<AssetRestVO>> assetByIPList = assetClient.getAssetByIPList(keyList);
        List<AssetRestVO> data = assetByIPList.getData();
        //组装
        for (String ip : keyList) {
            //多线程查询字段
            Future<Integer> vulSize = asyncExecutor.submit(this.getVulSize(Arrays.asList(ip), null, null, null));
            Future<Map> stateMap = asyncExecutor.submit(this.getStateMap(null, Arrays.asList(ip), null, null, null));
            Future<Map> vulSeveritysMap = asyncExecutor.submit(this.getVulSeverityMap(Arrays.asList(ip), null, null, null));
            //组装
            Integer vulSizeOne = vulSize.get();
            Map stateMapOne = stateMap.get();
            Map vulSeverity = vulSeveritysMap.get();
            Integer vulSeverityMax = vulSeverityMap.get(ip);
            String[] content = ipContent.get(ip).split("/");
            AssetRestVO assetVo=new AssetRestVO();
            if (!CollectionUtils.isEmpty(data)){
                assetVo = data.stream().filter(assetRestVO -> ip.equals(assetRestVO.getIp())).collect(Collectors.toList()).get(0);
            }
            PageVulByIpVo vulByIpVo = new PageVulByIpVo(content, vulSeverityMax, vulSizeOne, stateMapOne, vulSeverity, assetVo);
            vulByIpVoList.add(vulByIpVo);
        }
        //返回
        return ResultUtils.pageOk(vulByIpVoList, total);
    }





//算出数量
 public Callable<Integer> getVulSize(List<String> ipList, Integer bsId, Integer areaId, Integer orgId) {
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                if (!CollectionUtils.isEmpty(ipList)) {
                    boolQueryBuilder.must(QueryBuilders.termsQuery("ip", ipList));
                }
                if (null != bsId) {
                    boolQueryBuilder.must(QueryBuilders.matchQuery("bs_id", bsId));
                }
                if (null != areaId) {
                    boolQueryBuilder.must(QueryBuilders.matchQuery("area_id", areaId));
                }
                if (null != orgId) {
                    boolQueryBuilder.must(QueryBuilders.matchQuery("org_id", orgId));
                }

                //查询条件
                SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withIndices(TableEnums.VULCENTER_REAL_VUL_RESULT)
                        .withQuery(boolQueryBuilder)
                        .withCollapseField("code")
                        .build();
                //查询
                int count = (int) estTemplate.count(searchQuery);
                return count;

            }
        };
        return callable;

    }




  /**
     * 获取整改状态
     */
    public Callable<Map> getStateMap(String cveCode, List<String> ipList, Integer bsId, Integer areaId, Integer orgId) {
        Callable<Map> callable = new Callable<Map>() {
            @Override
            public Map call() throws Exception {
                Map<String, Integer> stateMap = new HashMap<>();
                stateMap.put("finish", 0);
                stateMap.put("doing", 0);
                stateMap.put("wait_submit", 0);
                stateMap.put("waiting_process", 0);
                stateMap.put("ignore", 0);
                //查询条件
                //查询整改状态条件
                for (RealVulStateEnum stateEnum : RealVulStateEnum.values()) {
                    int value = stateEnum.getValue();
                    //查询条件
                    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
                    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                    if (!StringUtils.isEmpty(cveCode)) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("cve_code", cveCode));
                    }
                    if (!CollectionUtils.isEmpty(ipList)) {
                        boolQueryBuilder.must(QueryBuilders.termsQuery("ip", ipList));
                    }
                    if (null != bsId) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("bs_id", bsId));
                    }
                    if (null != areaId) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("area_id", areaId));
                    }
                    if (null != orgId) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("org_id", orgId));
                    }
                    boolQueryBuilder.must(QueryBuilders.matchQuery("state", value));
                    nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
                    //过滤
                    nativeSearchQueryBuilder.withCollapseField("code");
                    nativeSearchQueryBuilder.withIndices(TableEnums.VULCENTER_REAL_VUL_RESULT);
                    long count = estTemplate.count(nativeSearchQueryBuilder.build());
                    switch (RealVulStateEnum.getRealVulStateEnum(value)) {
                        case PENDING:
                            stateMap.put("waiting_process", (int) count);
                            break;
                        case PROCESSING:
                            stateMap.put("doing", (int) count);
                            break;
                        case RECTIFIED:
                        case CHECKED:
                            stateMap.put("finish", stateMap.get("finish") + (int) count);
                            break;
                        case SUBMIT:
                        case SUBMIT_REJECT:
                            stateMap.put("wait_submit", stateMap.get("wait_submit") + (int) count);
                            break;
                        default:
                            stateMap.put("ignore", (int) count);
                            break;
                    }
                }
                return stateMap;
            }
        };
        return callable;

    }






/**
     * 获取风险等级
     *
     * @param asList
     * @return
     */
    private Callable<Map> getVulSeverityMap(List<String> asList, Integer bsId, Integer areaId, Integer orgId) {
        Callable<Map> callable = new Callable<Map>() {
            @Override
            public Map call() throws Exception {
                //初始化数量
                Map<String, Integer> vulSeverityMap = new HashMap<>();
                vulSeverityMap.put("super_risk", 0);
                vulSeverityMap.put("high_risk", 0);
                vulSeverityMap.put("medium_risk", 0);
                vulSeverityMap.put("low_risk", 0);
                vulSeverityMap.put("unknown", 0);
                //查询条件 依次统计5个风险等级
                for (VulSeverityEnum vulSeverityEnum : VulSeverityEnum.values()) {
                    int value = vulSeverityEnum.getValue();
                    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
                    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                    //查询条件
                    if (!CollectionUtils.isEmpty(asList)) {
                        boolQueryBuilder.must(QueryBuilders.termsQuery("ip", asList));
                    }
                    if (null != bsId) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("bs_id", bsId));
                    }
                    if (null != areaId) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("area_id", areaId));
                    }
                    if (null != orgId) {
                        boolQueryBuilder.must(QueryBuilders.matchQuery("org_id", orgId));
                    }
                    boolQueryBuilder.must(QueryBuilders.matchQuery("vul_severity", value));
                    nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
                    //过滤
                    nativeSearchQueryBuilder.withCollapseField("code");
                    nativeSearchQueryBuilder.withIndices(TableEnums.VULCENTER_REAL_VUL_RESULT);
                    long count = estTemplate.count(nativeSearchQueryBuilder.build());
                    switch (VulSeverityEnum.getVulSeverityEnum(value)) {
                        case UNKNOWN:
                            vulSeverityMap.put("unknown", (int) count);
                            break;
                        case LOW:
                            vulSeverityMap.put("low_risk", (int) count);
                            break;
                        case MEDIUM:
                            vulSeverityMap.put("medium_risk", (int) count);
                            break;
                        case HIGH:
                            vulSeverityMap.put("high_risk", (int) count);
                            break;
                        default:
                            vulSeverityMap.put("super_risk", (int) count);
                            break;
                    }
                }
                return vulSeverityMap;
            }
        };
        return callable;
    }

三、批量修改


        //批量修改状态
        List<UpdateQuery> updateQueryList = new ArrayList<>();
        IndexRequest indexRequest = new IndexRequest();
        indexRequest.source("state", RealVulStateEnum.PENDING.getValue());
        for (String id : idList) {
            UpdateQuery updateQuery = new UpdateQueryBuilder().withClass(RealVul.class).withId(id).withIndexRequest(indexRequest).build();
            updateQueryList.add(updateQuery);
        }
        estTemplate.bulkUpdate(updateQueryList);

四、对于数据很大的es进行统计分组,一次性的计算,可用startScroll 来进行计算文章来源地址https://www.toymoban.com/news/detail-403030.html

    /**
     * scroll游标快照超时时间,单位ms
     */
    private static final long SCROLL_TIMEOUT = 60 * 1000;

    /**
     * 多线程调用(线程池)
     */
    @Autowired
    public AsyncTaskExecutor asyncExecutor;

  public void selectVul() throws Exception {
   Future<Integer> vul = asyncExecutor.submit(this.vulInsertMysql(VulTypeEnum.IP_INSERT.getValue()));
、、、、、、、



}

 public Callable<Integer> vulInsertMysql(Integer type) {
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
                nativeSearchQueryBuilder.withPageable(PageRequest.of(0, 500));
                //分组
                nativeSearchQueryBuilder.addAggregation(
                        AggregationBuilders.terms("ip_group").field("ip").size(Integer.MAX_VALUE)
                                //风险等级
                                .subAggregation(AggregationBuilders.max("vul_severity_max").field("vul_severity"))
                );
                //漏洞
                AggregatedPage<RealVul> vulIp = (AggregatedPage<RealVul>) elasticsearchRestTemplate.startScroll(SCROLL_TIMEOUT, nativeSearchQueryBuilder.build(), RealVul.class);
                while (vulIp.hasContent()) {
                    List<VulIpSeverityInfo> vulList = vulIp.getContent().stream().map(e -> {
                        VulIpSeverityInfo vulIpSeverityInfo = new VulIpSeverityInfo(e.getIp(), e.getVulSeverity());
                        return vulIpSeverityInfo;
                    }).collect(Collectors.toList());
                    listToPage(vulList, type);
                    //取下一页,scrollId在es服务器上可能会发生变化,需要用最新的。发起continueScroll请求会重新刷新快照保留时间
                    vulIp = (AggregatedPage<RealVul>) elasticsearchRestTemplate.continueScroll(vulIp.getScrollId(), SCROLL_TIMEOUT, RealVul.class);
                }
                //及时释放es服务器资源
                log.info("漏洞表的ip全部取出");
                elasticsearchRestTemplate.clearScroll(vulIp.getScrollId());
                return 1;
            }
        };
        log.info("漏洞统计ip开始");
        return callable;

到了这里,关于实战中关于elasticsearch中的查询方法--高级查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ElasticSearch 实战:ES查询索引文档的6种方法

    在Elasticsearch中,查询索引文档的方法多种多样,这里列举了6种常见的查询方法,其中包括: 简单查询(String Query) 这是最基本的全文搜索,只需在URL后面附加查询字符串即可。例如,对索引 my_index 中的所有文档执行模糊匹配查询: Match Query 类似于简单查询,但提供了更多的

    2024年04月12日
    浏览(43)
  • Elasticsearch的高级查询

    目录 一、条件查询 1、单条件 1)路由查询  2)body体查询 2、多条件查询 1)and---must  2)or---should 3)范围---filter 3、全文检索、完全匹配、高亮显示  二、聚合查询 1、分组 2、求平均值 1)路由查询 方法:get url :http://localhost:9200/wenzhang/_search?q=name:蜡笔 介绍:q后面跟的是字

    2024年02月13日
    浏览(38)
  • 2、ElasticSearch高级查询

    下面这种写法,有没有body体,都可以查询所有文档,建议写上body体。 body体中的\\\"query\\\" 代表的是一个查询对象,里面可以有不同的查询属性。 \\\"match_all\\\"表示查询类型,match_all代表查询所有。还有 match,term , range 等查询类型,可以参考下面写法。 match 匹配类型查询,会把查询

    2024年02月16日
    浏览(40)
  • ElasticSearch高级查询

    本内容基本都是对请求体进行配置,也是 ElasticSearch 的语法核心所在。 查询都是用  GET  请求。 分词查询 在 Postman 中,向 ES 服务器发  GET  请求: http://127.0.0.1:9200/test/_search 请求体 查询“name”包含“zhangsan2”的数据 查询所有文档 在 Postman 中,向 ES 服务器发  GET  请求:

    2024年02月04日
    浏览(40)
  • ElasticSearch高级查询语法

    当数据写入ES时,数据将会通过“分词”被切分为不同的term,ES将term与其对应的文档列表建立一种映射关系,这种结构就是倒排索引。如下图所示: 为了进一步提升索引的效率,ES在term的基础上利用term的前缀或者后缀构建了term index,用于对term本身进行索引,ES实际的索引结

    2024年01月20日
    浏览(40)
  • Elasticsearch的高级查询技巧

    Elasticsearch是一个基于分布式、实时、高性能、高可扩展的搜索和分析引擎。它可以处理大量数据,提供快速、准确的搜索结果。Elasticsearch的查询技巧非常重要,可以帮助我们更有效地利用Elasticsearch的功能。 在Elasticsearch中,查询技巧主要包括以下几个方面: 查询语言(Query

    2024年02月21日
    浏览(56)
  • 七、ElasticSearch-高级查询操作三

    在进行搜索时,搜索出的内容中的会显示不同的颜色,称之为高亮。 Elasticsearch 可以对查询内容中的部分,进行标签和样式 ( 高亮 ) 的设置。 在使用 match 查询的同时,加上一个 highlight 属性: pre_tags :前置标签 post_tags :后置标签 fields :需要高亮的字段

    2023年04月08日
    浏览(30)
  • ElasticSearch(三)高级查询语法(DLS)

            1、单词词典:记录所有文档单词,单词到倒排列表的关系;         2、倒排列表:记录了单词对应的文档id;         3、倒排索引项:a 文档id b 词频 c 位置(单词在文本中的位置)d 偏移:单词开始结束位置; mapping映射类似于数据库的字段类型 put /索引名 {   

    2024年01月21日
    浏览(38)
  • Elasticsearch的高级查询技巧与优化

    Elasticsearch是一个基于分布式搜索和分析引擎,它可以提供实时、高性能、可扩展的搜索功能。在大数据时代,Elasticsearch在各种应用场景中发挥着重要作用。本文将深入探讨Elasticsearch的高级查询技巧与优化,帮助读者更好地掌握Elasticsearch的高级查询技能。 在深入探讨Elastic

    2024年03月19日
    浏览(51)
  • elasticsearch(es)高级查询api

    在以上示例代码中,定义了一个返回类型为ResponseEntityMapString, Object的/search POST映射方法,并使用MapString, Object对象来存储异步操作的结果。然后,创建了一个ActionListener的匿名实现对象,并使用client.searchAsync()方法以异步方式执行搜索操作。在onResponse()方法中,将搜索结果存储

    2023年04月09日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包