2021-10-25

Service
public class ClassificationOfDiseasesServiceImpl  {


    private static final Logger log = LoggerFactory.getLogger(ClassificationOfDiseasesServiceImpl.class);


    private final RestHighLevelClient client;

    public ClassificationOfDiseasesServiceImpl(RestHighLevelClient client) {
        this.client = client;
    }


    @Autowired
    private ClassificationClient classificationClient;

    //索引名称
    public static final String CLASSIFICATION_OF_DISEASES = "classificationofdiseases";


    /**
     * 单个新增
     *
     * @param id
     * @return
     */
    public BaseResponse insert(String id) {

        BaseRequest baseRequest = new BaseRequest();
        if (StringUtils.isEmpty(id)) {
            return BaseResponse.error();
        }
        BaseResponse baresponse = BaseResponse.success();

        baseRequest.setRequest(id);
        baseRequest.setHeaders(new Headers());
        BaseResponse<ClassificationOfDiseases> clientInfo = classificationClient.getInfo(baseRequest);


        IndexRequest request = new IndexRequest(CLASSIFICATION_OF_DISEASES);
        Map<String, Object> jsonMap = null;

        if (clientInfo != null && clientInfo.getResponse() != null) {
            jsonMap = JSONObject.parseObject(JSONObject.toJSONString(clientInfo.getResponse()), Map.class);
        } else {
            return BaseResponse.error();
        }
        //
        request.source(jsonMap);
        IndexResponse response = null;
        try {
            response = client.index(request, EsConfig.COMMON_OPTIONS);

            if (response.getResult().name().equalsIgnoreCase("created")) {
                return baresponse;
            } else {
                return BaseResponse.error();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return BaseResponse.error();
    }

    /**
     * 批量新增
     *
     * @param barequest
     * @return
     */
    public BaseResponse batchInsert(BaseRequest barequest) {

        BaseResponse response = BaseResponse.success();

        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setRequest("123");
        baseRequest.setHeaders(new Headers());
        //查询数据
        List<ClassificationOfDiseases> list = classificationClient.saveClassificationOfDiseases(baseRequest);
        if (list.size() <= 0) {
            return BaseResponse.error();
        }
        //批量从插入数据
        BulkRequest request = new BulkRequest();
        //设置分片超时时间 TimeValue.timeValueSeconds(1)
        //request.timeout("2m");
        //设置刷新策略,若未设置最常见的情况就是执行es中数据更新或插入,
        // 同步去查询时数据发现没有更新  WriteRequest.RefreshPolicy.WAIT_UNTIL
        //request.setRefreshPolicy("wait_for");
        //request.waitForActiveShards(3);

        //通过设置poType为“update”or“create”设置更新或者修改  DocWriteRequest.OpType.CREATE
        //request.opType("create");
        for (ClassificationOfDiseases dis : list) {
            Map<String, Object> item =
                    JSONObject.parseObject(JSONObject.toJSONString(dis), Map.class);
            request.add(new IndexRequest(CLASSIFICATION_OF_DISEASES).
                    source(item));
        }
        try {
            BulkResponse bulk = client.bulk(request, EsConfig.COMMON_OPTIONS);
            if (bulk.status().getStatus() == 200) {
                return response;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


        return BaseResponse.error();
    }


    /**
     * 创建索引
     * @return
     * @throws IOException
     */
    public BaseResponse createIndex() throws IOException {
        BaseResponse response = BaseResponse.success();

        try{

            CreateIndexRequest request = new CreateIndexRequest(CLASSIFICATION_OF_DISEASES);

            Settings.Builder builder = Settings.builder();
            // 分片数
            builder.put("index.number_of_shards", 3);
            // 副本数
            builder.put("index.number_of_replicas", 2);
            builder.put("analysis.analyzer.default.tokenizer", "ik_max_word");
            // 默认分词器
            request.settings(builder);

            CreateIndexResponse createIndexResponse = client.indices().create(request, EsConfig.COMMON_OPTIONS);
            if (createIndexResponse.isShardsAcknowledged()){
                return  response;
            }
        }catch (Exception e){
            response.setCode("400");
            response.setMessage(e.getMessage());
            return  response;
        }
        return  BaseResponse.error();
    }





    /**
     * 修改
     *
     * @param reque
     * @return
     */
    public BaseResponse update(String id, BaseRequest<ClassificationOfDiseases> reque) {


        ClassificationOfDiseases requ = reque.getRequest();

        BaseResponse response = BaseResponse.success();
        Map<String, Object> map = null;

        map = JSONObject.parseObject(JSONObject.toJSONString(requ), Map.class);

        UpdateRequest request = new
                UpdateRequest(CLASSIFICATION_OF_DISEASES, map.get("id").toString()).doc(map);
        //目标doc有就更新、没有就新增
        request.docAsUpsert(false);
        try {
            UpdateResponse update = client.update(request, EsConfig.COMMON_OPTIONS);
            if (update.status().getStatus() == 200) {
                return response;
            } else {
                return BaseResponse.error();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }






    /**
     * 查询 疾病
     * @param barequest
     * @return
     */
    public BaseResponse queryIllness(BaseRequest<ClassificationOfDiseases> barequest) {
        BaseResponse response = BaseResponse.success();
        //
        if (null == barequest || barequest.getRequest() == null) {
            response.setCode("201");
            response.setMessage("请求数据为空!");
            return response;
        }
        if (StringUtils.isEmpty( barequest.getRequest().getDiseasesName())){
            response.setCode("201");
            response.setMessage("请求疾病名称数据为空!");
            return response;
        }
        SearchRequest request = new SearchRequest(CLASSIFICATION_OF_DISEASES);
        ClassificationOfDiseases ofDiseases = barequest.getRequest();
        //疾病名称
        String diseasesName = ofDiseases.getDiseasesName();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //或者
        //boolQueryBuilder.should(QueryBuilders.termQuery("diseasName",diseasName));

        boolQueryBuilder.filter(QueryBuilders.termQuery("diseasesName.keyword", diseasesName));

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //分页
        searchSourceBuilder.from(0).size(10);
        searchSourceBuilder.query(boolQueryBuilder);
        //
        request.searchType(SearchType.DEFAULT).source(searchSourceBuilder);
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            SearchResponse searchResponse = client.search(request, EsConfig.COMMON_OPTIONS);
            for (SearchHit s : searchResponse.getHits().getHits()) {
                //
                Map<String, Object> sourceAsMap = s.getSourceAsMap();
                list.add(sourceAsMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (list.size() <= 0) {
            response.setCode("201");
            response.setMessage("查询数据为空!");
            return response;
        }
        response.setResponse(list);
        return response;
    }





    /**
     * 查询
     * @param barequest
     * @return
     */
    public BaseResponse queryDiseases(BaseRequest<ClassificationOfDiseases> barequest) {
        BaseResponse response = BaseResponse.success();
        //
        if (null == barequest || barequest.getRequest() == null) {
            response.setCode("201");
            response.setMessage("请求数据为空!");
            return response;
        }
        if (StringUtils.isEmpty( barequest.getRequest().getDiseasesName())){
            response.setCode("201");
            response.setMessage("请求数据为空!");
            return response;
        }
        SearchRequest request = new SearchRequest(CLASSIFICATION_OF_DISEASES);
        ClassificationOfDiseases ofDiseases = barequest.getRequest();
        //疾病名称
        String diseasesName = ofDiseases.getDiseasesName();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        boolQueryBuilder.filter(QueryBuilders.termQuery("diseasesName.keyword", diseasesName));

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //分页
        searchSourceBuilder.from(0).size(100);
        searchSourceBuilder.query(boolQueryBuilder);
        //
        request.searchType(SearchType.DEFAULT).source(searchSourceBuilder);
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            SearchResponse searchResponse = client.search(request, EsConfig.COMMON_OPTIONS);
            for (SearchHit s : searchResponse.getHits().getHits()) {
                //
                Map<String, Object> sourceAsMap = s.getSourceAsMap();
                list.add(sourceAsMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (list.size() <= 0) {
            response.setCode("201");
            response.setMessage("查询数据为空!");
            return response;
        }
        response.setResponse(list);
        return response;
    }


    public BaseResponse queryId(BaseRequest<Map<String ,Object>> barequest) {
        BaseResponse response = BaseResponse.success();
        //
        if (null == barequest || barequest.getRequest().isEmpty()) {
            response.setCode("201");
            response.setMessage("请求数据为空!");
            return response;
        }
        SearchRequest request = new SearchRequest(CLASSIFICATION_OF_DISEASES);
         Map<String, Object> map = barequest.getRequest();
        String id = (String)map.get("id");
        //疾病名称
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.filter(QueryBuilders.termQuery("id.keyword", id));
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //分页
        searchSourceBuilder.from(0).size(100);
        searchSourceBuilder.query(boolQueryBuilder);
        //
        request.searchType(SearchType.DEFAULT).source(searchSourceBuilder);
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            SearchResponse searchResponse = client.search(request, EsConfig.COMMON_OPTIONS);
            for (SearchHit s : searchResponse.getHits().getHits()) {
                //
                Map<String, Object> sourceAsMap = s.getSourceAsMap();
                list.add(sourceAsMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (list.size() <= 0) {
            response.setCode("201");
            response.setMessage("查询数据为空!");
            return response;
        }
        response.setResponse(list);
        return response;
    }


    /**
     * 1:ik_smart:做最粗粒度的拆分;2:ik_max_word:做最细粒度的拆分
     * @param barequest
     * @return
     */
    public BaseResponse queryIk_max_word(BaseRequest<ClassificationOfDiseases> barequest) {
        BaseResponse response = BaseResponse.success();
        //
        if (null == barequest || barequest.getRequest() == null) {
            return BaseResponse.error();
        }
        SearchRequest request = new SearchRequest(CLASSIFICATION_OF_DISEASES);
        ClassificationOfDiseases ofDiseases = barequest.getRequest();
        String diseasesName = ofDiseases.getDiseasesName();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //ik_smart 为最少切分
        //ik_max_word为细粒度划分!会去匹配字典!
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("diseasesName", diseasesName).analyzer("ik_smart");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //分页
        searchSourceBuilder.from(0).size(100);
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.query(matchQueryBuilder);
        //
        request.searchType(SearchType.DEFAULT).source(searchSourceBuilder);
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            SearchResponse searchResponse = client.search(request, EsConfig.COMMON_OPTIONS);
            for (SearchHit s : searchResponse.getHits().getHits()) {
                Map<String, Object> sourceAsMap = s.getSourceAsMap();
                list.add(sourceAsMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (list.size() <= 0) {
            response.setCode("201");
            response.setMessage("查询数据为空!");
            return response;
        }
        response.setResponse(list);
        return response;
    }


    /**
     *  查询疾病库 中的症状与疾病名称
     * @param request
     * @return
     */
    public BaseResponse<    List<Map<String, Object>>> refer(BaseRequest<Map<String, Object>> request){
        BaseResponse response = BaseResponse.success();
        if (null == request || request.getRequest() == null) {

            response.setCode("201");
            response.setMessage("请求数据异常!");
            return response;
        }
        //检索的内容
        String name=(String)request.getRequest().get("name");

        SearchRequest req = new SearchRequest(CLASSIFICATION_OF_DISEASES);

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        boolQueryBuilder.filter(QueryBuilders.multiMatchQuery(name,
                "diseasesName",
                "singsAndSymptoms"
                ));

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //根据中文分词进行查询
        //searchSourceBuilder.query(matchQueryBuilder);
        //分页
        searchSourceBuilder.from(0).size(100);
        searchSourceBuilder.query(boolQueryBuilder);



        req.searchType(SearchType.DEFAULT).source(searchSourceBuilder);

        List<Map<String, Object>> list = new ArrayList<>();
        SearchHit[] hits1 = null;
        try {
            SearchResponse searchResponse = client.search(req, EsConfig.COMMON_OPTIONS);
            for (SearchHit s : searchResponse.getHits().getHits()) {
                Map<String, Object> sourceAsMap = s.getSourceAsMap();
                list.add(sourceAsMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        response.setResponse(list);
        return response;



    }



    /** 查询全部
     * @param barequest
     * @return
     */
    public BaseResponse query(BaseRequest<ClassificationOfDiseases> barequest) {

        if (null == barequest || barequest.getRequest() == null) {
            return BaseResponse.error();
        }
        ClassificationOfDiseases ofDiseases = barequest.getRequest();
        String diseasesName = ofDiseases.getDiseasesName();
        String andPathology = ofDiseases.getEtiologyAndPathology();
        String administrativeOffice = ofDiseases.getAdministrativeOffice();
        String briefIntroduction = ofDiseases.getBriefIntroduction();
        String cure = ofDiseases.getCure();
        String diagnose = ofDiseases.getDiagnose();
        String examine = ofDiseases.getExamine();
        String prevent = ofDiseases.getPrevent();
        //String prognosis = ofDiseases.getPrognosis();
        String singsAndSymptoms = ofDiseases.getSingsAndSymptoms();
        String typeName = ofDiseases.getTypeName();

        BaseResponse response = BaseResponse.success();
        SearchRequest request = new SearchRequest(CLASSIFICATION_OF_DISEASES);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //term的查询是代表完全匹配,搜索之前不进行分词
        //terms和term一样,不进行分词。terms针对一个字段包含多个值得时候使用类似 IN

        //或者
        //boolQueryBuilder.should(QueryBuilders.termQuery("diseaseReason",diseaseReason));

        //并且
        if (!StringUtils.isEmpty(diseasesName)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("diseasesName", diseasesName));
        }
        //并且
        if (!StringUtils.isEmpty(andPathology)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("andPathology", andPathology));
        }
       /* RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("typeName").from(typeName);
        //
        if (cure != null && cure > 0) {
            rangeQueryBuilder.to(cure);
        }*/
        //boolQueryBuilder.filter(rangeQueryBuilder);

      /*  Map<String, String> queryList =new HashMap<String, String>();
        queryList.put("singsAndSymptoms","撒大声地自行车道三");

        for (Map.Entry<String, String> entry :queryList.entrySet()) {
            boolQueryBuilder.should(QueryBuilders.matchPhraseQuery(entry.getKey(),entry.getValue()));
        }*/

        //根据中文分词进行查询
        //MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("diseasesName",diseasesName).analyzer("ik_smart");

        if (!StringUtils.isEmpty(diseasesName)) {
            //不分词查
            //boolQueryBuilder.filter(QueryBuilders.prefixQuery("diseasesName.keyword", diseasesName));

            //boolQueryBuilder.filter(QueryBuilders.fuzzyQuery("diseasesName", diseasesName));
            //boolQueryBuilder.should(QueryBuilders.termQuery("andPathology", andPathology));
            // boolQueryBuilder.should(QueryBuilders.termQuery("administrativeOffice", administrativeOffice));
            // boolQueryBuilder.should(QueryBuilders.termQuery("briefIntroduction", briefIntroduction));
            // boolQueryBuilder.should(QueryBuilders.termQuery("cure", cure));
            // boolQueryBuilder.should(QueryBuilders.termQuery("diagnose", diagnose));
            // boolQueryBuilder.should(QueryBuilders.termQuery("examine", examine));
            // boolQueryBuilder.should(QueryBuilders.termQuery("prevent", prevent));
            // boolQueryBuilder.should(QueryBuilders.termQuery("prognosis", prognosis));
            // boolQueryBuilder.should(QueryBuilders.termQuery("singsAndSymptoms", singsAndSymptoms));
            // boolQueryBuilder.should(QueryBuilders.termQuery("typeName", diseasesName));
            //boolQueryBuilder.should(QueryBuilders.termQuery("diseasName",diseasName));
            //boolQueryBuilder.must(QueryBuilders.matchQuery("diseasesName", diseasesName));
        }

        //prognosis满足模糊匹配prognosis字段
        //boolQueryBuilder.filter(QueryBuilders.matchQuery("prognosis", prognosis));
        //匹配 唐人 或者 2号
        //boolQueryBuilder.must(QueryBuilders.matchQuery("prognosis", "唐人 2号").operator(Operator.OR));
        //匹配 唐人 并且 2号
        //boolQueryBuilder.must(QueryBuilders.matchQuery("prognosis", "唐人 2号").operator(Operator.AND));
        //multi_match 多个字段field匹配一个值,模糊查询
        boolQueryBuilder.filter(QueryBuilders.multiMatchQuery(diseasesName,
                "diseasesName",
                "andPathology",
                "administrativeOffice",
                "briefIntroduction",
                "cure",
                "diagnose",
                "examine",
                "prevent",
                "prognosis",
                "singsAndSymptoms",
                "typeName",
                "diseasName",
                "diseasesName"));

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //根据中文分词进行查询
        //searchSourceBuilder.query(matchQueryBuilder);
        //分页
        searchSourceBuilder.from(0).size(100);
        searchSourceBuilder.query(boolQueryBuilder);

        //searchSourceBuilder 高亮设置
        searchSourceBuilder.highlighter(getHighlightBuilder());

        request.searchType(SearchType.DEFAULT).source(searchSourceBuilder);

        List<Map<String, Object>> list = new ArrayList<>();
        SearchHit[] hits1 = null;
        try {
            SearchResponse searchResponse = client.search(request, EsConfig.COMMON_OPTIONS);
            for (SearchHit s : searchResponse.getHits().getHits()) {

                Map<String, Object> sourceAsMap = s.getSourceAsMap();
                Map<String, HighlightField> highlightFieldsMap = s.getHighlightFields();
                //获取高亮查询的结果并覆盖正常查询到的数据
                sourceAsMap = getHighLightMap(sourceAsMap, highlightFieldsMap);
                list.add(sourceAsMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        response.setResponse(list);
        return response;
    }


    /**
     * 高亮设置
     *
     * @return
     */
    private HighlightBuilder getHighlightBuilder() {
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='#e75213'>");
        highlightBuilder.postTags("</font>");
        /**
         * highlighterType可选:unified,plain和fvh
         * unified : 使用Lucene的统一highlighter。
         * 这个突出显示器将文本分成句子,并使用BM25算法对单个句子进行评分,
         * 就好像它们是语料库中的文档一样。它还支持准确的短语和多项(模糊,前缀,正则表达式)突出显示
         *
         *plain highlighter最适合在单一领域突出简单的查询匹配。
         * 为了准确反映查询逻辑,它会创建一个微小的内存索引,
         * 并通过Lucene的查询执行计划程序重新运行原始查询条件,
         * 以访问当前文档的低级匹配信息。对于需要突出显示的每个字段和每个文档都会
         * 重复此操作。如果要在复杂查询的大量文档中突出显示很多字段,
         * 我们建议使用unified highlighter postings或term_vector字段
         *
         *fvh highlighter使用Lucene的Fast Vector highlighter。此突出显示器可用于映射中term_vector设置为的
         * 字段with_positions_offsets。Fast Vector highlighter
         */
        highlightBuilder.highlighterType("unified");
        /**
         * 这只高亮字段,我这里设置为要查询的字段一致
         */
        highlightBuilder
                .field("diseasesName")
                .field("andPathology")
                .field("administrativeOffice")
                .field("briefIntroduction")
                .field("cure")
                .field("diagnose")
                .field("examine")
                .field("prevent")
                .field("prognosis")
                .field("singsAndSymptoms")
                .field("typeName");

        //如果要多个字段高亮,这项要为false
        highlightBuilder.requireFieldMatch(false);
        /**
         * fragmentSize  设置要显示出来的fragment文本判断的长度,默认是100
         * numOfFragments 代表要显示几处高亮(可能会搜出多段高亮片段)。默认是5
         * noMatchSize  即使字段中没有关键字命中,也可以返回一段文字,该参数表示从开始多少个字符被返回
         */
        //highlightBuilder.fragmentSize(size).numOfFragments(3).noMatchSize(100);

        return highlightBuilder;
    }


    /**
     * 高亮结果返回
     * 正常查询和高亮查询分开返回的,也就是高亮部分数据不会影响正常数据
     * 这里要用高亮数据覆盖正常返回数据,这样返回前端就是匹配的都是高亮显示了
     **/
    private Map<String, Object> getHighLightMap(Map<String, Object> map, Map<String, HighlightField> highlightFields) {
        HighlightField diseasesName = highlightFields.get("diseasesName");
        HighlightField andPathology = highlightFields.get("andPathology");
        HighlightField administrativeOffice = highlightFields.get("administrativeOffice");
        HighlightField briefIntroduction = highlightFields.get("briefIntroduction");
        HighlightField cure = highlightFields.get("cure");
        HighlightField diagnose = highlightFields.get("diagnose");
        HighlightField examine = highlightFields.get("examine");
        HighlightField prevent = highlightFields.get("prevent");

        HighlightField prognosis = highlightFields.get("prognosis");
        HighlightField singsAndSymptoms = highlightFields.get("singsAndSymptoms");
        HighlightField typeName = highlightFields.get("typeName");

        if (diseasesName != null) {
            map.put("diseasesName", diseasesName.fragments()[0].string());
        }
        if (andPathology != null) {
            map.put("andPathology", andPathology.fragments()[0].string());
        }
        if (administrativeOffice != null) {
            map.put("administrativeOffice", administrativeOffice.fragments()[0].string());
        }
        if (briefIntroduction != null) {
            map.put("briefIntroduction", briefIntroduction.fragments()[0].string());
        }
        if (cure != null) {
            map.put("cure", cure.fragments()[0].string());
        }
        if (diagnose != null) {
            map.put("diagnose", diagnose.fragments()[0].string());
        }
        if (examine != null) {
            map.put("examine", examine.fragments()[0].string());
        }
        if (prevent != null) {
            map.put("prevent", prevent.fragments()[0].string());
        }
        if (prognosis != null) {
            map.put("prognosis", prognosis.fragments()[0].string());
        }
        if (singsAndSymptoms != null) {
            map.put("singsAndSymptoms", singsAndSymptoms.fragments()[0].string());
        }
        if (typeName != null) {
            map.put("typeName", typeName.fragments()[0].string());
        }
        return map;
    }


    /**
     * 这里以最多3个字段来分组统计(可以是1个,2个,3个 来做统计)
     **/
    public Map<String, Object> multiField3Aggregation(String field1, String field2, String field3) {

        Map<String, Object> data = new HashMap<>();
        data.clear();
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        ssb = getDifferentFieldRequestResult(ssb, field1, field2, field3, 500);

        request.source(ssb);
        SearchResponse response = null;
        Map<String, Long> resultMap = new HashMap<>();
        resultMap.clear();
        try {
            response = client.search(request, EsConfig.COMMON_OPTIONS);
             // 从这里分支 获取返回参数
            resultMap = getDifferentFieldResponseResult(field1, field2, field3, response);
            Map<String, Object> arrAfterSort = getArrAfterSort(resultMap, 500);
            return arrAfterSort;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 分组统计的核心部分
     * numbers是要返回的数据条数
     **/
    private SearchSourceBuilder getDifferentFieldRequestResult(SearchSourceBuilder ssb,
                                                               String groupField,
                                                               String groupNum2Field,
                                                               String groupNum3Field,
                                                               Integer numbers) {
        if (!org.apache.commons.lang.StringUtils.isBlank(groupField)
                && org.apache.commons.lang.StringUtils.isBlank(groupNum2Field)
                && org.apache.commons.lang.StringUtils.isBlank(groupNum3Field)) {

            ssb.aggregation(AggregationBuilders
                    .terms(groupField + "Agg")
                    .field(groupField + ".keyword")
                    .order(BucketOrder.count(false))
                    .size(numbers));
        } else if (!StringUtils.isBlank(groupField)
                && !StringUtils.isBlank(groupNum2Field)
                && StringUtils.isBlank(groupNum3Field)) {
            if (groupField.equalsIgnoreCase(groupNum2Field)) {
                throw new RuntimeException("查询字段为空!");
            }
            TermsAggregationBuilder field1Aggregation = getTermsAggregationBuilder(groupField);
            TermsAggregationBuilder field2Aggregation = getTermsAggregationBuilder(groupNum2Field);
            //里外都去23,23x23=529 满足最多查500条的最小数的平方
            field1Aggregation.subAggregation(field2Aggregation.order(BucketOrder.count(false)).size(23));
            ssb.aggregation(field1Aggregation.order(BucketOrder.count(false)).
                    size(50));

        } else if (!StringUtils.isBlank(groupField)
                && !StringUtils.isBlank(groupNum2Field)
                && !StringUtils.isBlank(groupNum3Field)) {
            if (groupField.equalsIgnoreCase(groupNum2Field)
                    || groupField.equalsIgnoreCase(groupNum3Field)
                    || groupNum2Field.equalsIgnoreCase(groupNum3Field)) {
                throw new RuntimeException("查询字段为空!");
            }
            TermsAggregationBuilder field1Aggregation = getTermsAggregationBuilder(groupField);
            TermsAggregationBuilder field2Aggregation = getTermsAggregationBuilder(groupNum2Field);
            TermsAggregationBuilder field3Aggregation = getTermsAggregationBuilder(groupNum3Field);

            field2Aggregation.subAggregation(field3Aggregation.order(BucketOrder.count(false)).size(8));
            field1Aggregation.subAggregation(field2Aggregation.order(BucketOrder.count(false)).size(8));
            ssb.aggregation(field1Aggregation.order(BucketOrder.count(false)).size(8));
        } else if (!StringUtils.isBlank(groupField)
                && StringUtils.isBlank(groupNum2Field)
                && !StringUtils.isBlank(groupNum3Field)) {
            throw new RuntimeException("查询字段为空!");
        }
        return ssb;
    }


    /**
     * 传入字段获取TermsAggregationBuilder对象
     */
    private TermsAggregationBuilder getTermsAggregationBuilder(String fieldName) {

        TermsAggregationBuilder fieldNameAggregation = AggregationBuilders
                .terms(fieldName + "Agg")
                .field(fieldName + ".keyword");

        return fieldNameAggregation;
    }


    /**
     * 根据 不同分组字段个数 进行分组 返回参数
     *
     * @param groupField
     * @param groupNum2Field
     * @param groupNum3Field
     * @param response
     * @return
     */
    private Map<String, Long> getDifferentFieldResponseResult(
            String groupField,
            String groupNum2Field,
            String groupNum3Field,
            SearchResponse response) {
        Map<String, Long> map = new HashMap<>();
        map.clear();
        if (!StringUtils.isBlank(groupField)
                && StringUtils.isBlank(groupNum2Field)
                && StringUtils.isBlank(groupNum3Field)) {
            Aggregations aggregations = response.getAggregations();
            ParsedStringTerms parsedStringTerms = aggregations.get(groupField + "Agg");
            List<? extends Terms.Bucket> buckets = parsedStringTerms.getBuckets();
            for (Terms.Bucket bucket : buckets) {
                String key = bucket.getKey().toString();
                long docCount = bucket.getDocCount();
                map.put(key, docCount);
            }
        } else if (!StringUtils.isBlank(groupField)
                && !StringUtils.isBlank(groupNum2Field)
                && StringUtils.isBlank(groupNum3Field)) {
            Terms agg = response.getAggregations().get(groupField + "Agg");

            for (Terms.Bucket entry : agg.getBuckets()) {
                String key = entry.getKey().toString();
                long docCount = entry.getDocCount();
                Terms Terms2 = entry.getAggregations().get(groupNum2Field + "Agg");
                for (Terms.Bucket entry2 : Terms2.getBuckets()) {
                    String key2 = entry2.getKey().toString();
                    long docCount2 = entry2.getDocCount();
                    map.put(key + "," + key2, docCount2);
                }
            }
        } else if (!StringUtils.isBlank(groupField)
                && !StringUtils.isBlank(groupNum2Field)
                && !StringUtils.isBlank(groupNum3Field)) {
            Terms agg = response.getAggregations().get(groupField + "Agg");

            for (Terms.Bucket entry : agg.getBuckets()) {

                String key1 = entry.getKey().toString();
                long docCount1 = entry.getDocCount();
                Terms terms = entry.getAggregations().get(groupNum2Field + "Agg");
                for (Terms.Bucket en : terms.getBuckets()) {
                    String key2 = en.getKey().toString();
                    long docCount2 = en.getDocCount();

                    Terms term = en.getAggregations().get(groupNum3Field + "Agg");
                    for (Terms.Bucket ent : term.getBuckets()) {
                        String key3 = ent.getKey().toString();
                        long docCount3 = ent.getDocCount();

                        map.put(key1 + "," + key2 + "," + key3, docCount3);
                    }
                }
            }
        }
        return map;


    }


    public static Map<String, Object> getArrAfterSort(Map<String, Long> m, int d) {
        Map<String, Object> map = new HashMap<>();
        map.clear();
        List<Map.Entry<String, Long>> list = new ArrayList<>(m.entrySet());
        Collections.sort(list, (o1, o2) -> {
            int flag = o1.getValue().compareTo(o2.getValue());
            if (flag == 0) {
                return o1.getKey().compareTo(o2.getKey());
            }
            return flag;
        });
        Long[] valueArr = new Long[list.size()];
        String[] keyStr = new String[list.size()];
        int i = 0;
        for (Map.Entry<String, Long> en : list) {

            valueArr[i] = en.getValue();
            keyStr[i] = en.getKey();
            i++;
        }
        map.put("xAis", keyStr);
        map.put("yAis", valueArr);
        return map;
    }

    /**
     * 类似mysql的 where id in (id1,id2,id3)
     *
     * @param args
     */
    public Map<String, Object> maIn(String[] args) {
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //核心部分
        boolQueryBuilder.filter(QueryBuilders.idsQuery()
                .addIds(args[0]));
        builder.query(boolQueryBuilder);
        request.source(builder);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            map.put("data", list);
           
        } catch (IOException e) {
            e.printStackTrace();
        }

        return  map;
    }

    //创建索引方法,传入索引名和类型名
    public BaseResponse reCreateIndex(String index, String type) {

        BaseResponse response = BaseResponse.success();

        return response;
    }

    /**
     * 新增修改
     *
     * @param indexName
     * @param type
     * @param id
     * @param jsonStr
     */
    public void addData(String indexName, String type, String id, String jsonStr) {
        try {
            // 1、创建索引请求  //索引  // mapping type  //文档id
            IndexRequest request = new IndexRequest(indexName, type, id);     //文档id
            // 2、准备文档数据
            // 直接给JSON串
            request.source(jsonStr, XContentType.JSON);
            //4、发送请求
            IndexResponse indexResponse = null;
            try {
                // 同步方式
                indexResponse = client.index(request, EsConfig.COMMON_OPTIONS);
            } catch (Exception e) {
                // 捕获,并处理异常
                //判断是否版本冲突、create但文档已存在冲突
                /*if (e.status() == RestStatus.CONFLICT) {
                    log.info("冲突了,请在此写冲突处理逻辑!" + e.getDetailedMessage());
                }*/
            }
            //5、处理响应
            if (indexResponse != null) {
                String index1 = indexResponse.getIndex();
                String type1 = indexResponse.getType();
                String id1 = indexResponse.getId();
                long version1 = indexResponse.getVersion();
                if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
                    log.info("======新增文档成功!=======" + index1 + type1 + id1 + version1);
                } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
                    log.info("=====修改文档成功!========");
                }
                // 分片处理信息
                ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
                if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
                    log.info("========分片处理信息.....======");
                }
                // 如果有分片副本失败,可以获得失败原因信息
                if (shardInfo.getFailed() > 0) {
                    for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
                        String reason = failure.reason();
                        log.info("======副本失败原因:======" + reason);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 批量插入
     *
     * @param indexName
     * @param type
     * @param idName
     * @param list
     */
    public void bulkDate(String indexName,
                         String type,
                         String idName,
                         List<Map<String, Object>> list) {
        try {

            if (null == list || list.size() <= 0) {
                return;
            }
            if (StringUtils.isBlank(indexName)
                    || StringUtils.isBlank(idName)
                    || StringUtils.isBlank(type)) {
                return;
            }
            BulkRequest request = new BulkRequest();
            for (Map<String, Object> map : list) {
                if (map.get(idName) != null) {

                    request.add(new IndexRequest(indexName,
                            type, String.valueOf(map.get(idName)))
                            .source(map, XContentType.JSON));
                }
            }
            // 2、可选的设置

            request.timeout("2m");
            request.setRefreshPolicy("wait_for");
            request.waitForActiveShards(2);

            //3、发送请求
            // 同步请求
            BulkResponse bulkResponse = client.bulk(request, EsConfig.COMMON_OPTIONS);
            //4、处理响应
            if (bulkResponse != null) {
                for (BulkItemResponse bulkItemResponse : bulkResponse) {
                    DocWriteResponse itemResponse = bulkItemResponse.getResponse();

                    if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
                            || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {
                        IndexResponse indexResponse = (IndexResponse) itemResponse;

                        log.info("======新增成功,{}=========" + indexResponse.toString());
                    } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {
                        UpdateResponse updateResponse = (UpdateResponse) itemResponse;

                        log.info("======修改成功,{}=========" + updateResponse.toString());
                    } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) {
                        DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
                        log.info("======删除成功,{}=========" + deleteResponse.toString());
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 前缀查询,可以通过一个关键字去指定一个field的前缀,从而查询到指定文档
     *
     * @param args
     */
    public void mains(String[] args) {
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //模糊查询:输入字符大概,es就会根据输入内容去匹配结果(有一点错别字也可以查到,一般不推荐这种方式使用)
        //boolQueryBuilder.filter( QueryBuilders.fuzzyQuery("name" ,"王"));

        //前缀查询 可以通过一个关键字去指定一个field的前缀,从而查询到指定文档
        boolQueryBuilder.filter(QueryBuilders.prefixQuery("name.keyword", "王"));
        builder.query(boolQueryBuilder);

        request.source(builder);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            map.put("data", list);
            // return R.ok("查询成功!").put("result", map);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 通配查询: 与MYSQL中的like是一样的,在查询时可以指定通配符和占位符
     * *是通配符 ?是占位符
     *
     * @param args
     */
    public void mainss(String[] args) {

        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //boolQueryBuilder.filter(QueryBuilders.wildcardQuery("name.keyword","hz"));
        boolQueryBuilder.filter(QueryBuilders.wildcardQuery("name.keyword", "hh??"));

        // range查询:只针对数值类型范围查询{大于:gt,小于:lt,大于等于:gte,小于等于:lte}
        // boolQueryBuilder.filter(QueryBuilders.rangeQuery("height").gt(170).lte(190));

        //regexp查询(prefix、wildcard、regexp、fuzzy查询效率低,谨慎使用,尽量避免)
        //boolQueryBuilder.filter(QueryBuilders.regexpQuery("age","2[0-9]{1}"));
        builder.query(boolQueryBuilder);

        // 分页查询
        builder.from(0).size(20);
        request.source(builder);
        //log.info("======="+builder);


        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            map.put("data", list);
            //return R.ok("查询成功!").put("result", map);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //复合过滤器,将多个查询条件以一定的逻辑组合在一起
    //must:-----类似mysql的and
    //must_not:类似mysql的not
    //should :----类似mysql的or java例子
    public void mainsss(String[] args) {
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //或者
        boolQueryBuilder.should(QueryBuilders.termQuery("job", "程序员"));
        boolQueryBuilder.should(QueryBuilders.termQuery("job", "教师"));
        //不是(非)
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("name", "张三"));
        //并且
        boolQueryBuilder.must(QueryBuilders.matchQuery("address", "百草"));
        boolQueryBuilder.must(QueryBuilders.matchQuery("address", "13"));
        builder.query(boolQueryBuilder);
        request.source(builder);

        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            map.put("data", list);
            // return R.ok("查询成功!").put("result", map);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * @param args
     */
    public void ma(String[] args) {
        //1.创建DeleteByQueryRequest
        DeleteByQueryRequest request = new DeleteByQueryRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        //2、指定检索条件
        request.setQuery(QueryBuilders.rangeQuery("height").lte(170));
        try {
            //执行删除
            BulkByScrollResponse response =
                    client.deleteByQuery(request, EsConfig.COMMON_OPTIONS);
            //log.info("删除成功,返回:"+response);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * boosting查询
     * 帮助我们去影响查询后的分数score
     * *positive 只有匹配到positive的查询内容,才会放到结果集
     * *negative 同时匹配上positive和negative,那么会降低文档得分 negative_boost指定系数,小于1.
     *
     * @param args
     */
    public void mn(String[] args) {
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);

        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoostingQueryBuilder boostingQueryBuilder = QueryBuilders.boostingQuery(
                QueryBuilders.matchQuery("address", "百"),
                QueryBuilders.matchQuery("name", "珊")
        ).negativeBoost(0.3f);
        builder.query(boostingQueryBuilder);
        request.source(builder);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            map.put("data", list);
            // return R.ok("查询成功!").put("result", map);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    // filter
    // query:根据查询条件,去计算文档匹配度得到一个分数,并根据分数进行排序,不做缓存
    // filter:根据查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进行缓存
    public void maghin(String[] args) {


        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(QueryBuilders.termQuery("name.keyword", "王思思"));
        builder.query(boolQueryBuilder);
        request.source(builder);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            map.put("data", list);
            //return R.ok("查询成功!").put("result", map);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 高亮就是用户输入关键字,以一定特殊样式展示给用户,让用户知道为什么这个结果被检索出来
     * 高亮展示数据,本身就是文档中的一个field,单独将field以highlight的形式返回给你
     * ES提供一个highlight属性,和query同级别
     * 1、fragment_size:指定高亮数据展示多少个字符回来
     * 2、pre_tags:指定前缀标签<font color="red">
     * 3、post_tags:指定后缀标签</font>
     * 4、fields:指定哪个field以高亮形式返回
     *
     * @param keyWord
     * @return
     */
    public Map<String, Object> getKeyWordHighLightQuery(String keyWord) {
        Integer start = 0;
        Integer limit = 10;
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (!StringUtils.isBlank(keyWord)) {
            /**
             * QueryBuilders.multiMatchQuery 多个字段field匹配一个值,模糊查询:
             * 第一参数是输入的要查询的值,后面的都是要匹配的字段
             */
            boolQueryBuilder
                    .filter(QueryBuilders.multiMatchQuery(
                            keyWord,
                            "companyCode",
                            "loginType",
                            "userId",
                            "appid",
                            "loginIp",
                            "unitCode",
                            "id",
                            "userType",
                            "isInWhitlelist",
                            "env"));

        }
        ssb.query(boolQueryBuilder);
        ssb.trackTotalHits(true);
        ssb.highlighter(getHighlightBuilder());
        request.source(ssb);
        SearchResponse response = null;
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        list.clear();
        map.clear();
        log.info("==输出执行搜索的语句:====" + request);
        try {
            response = client.search(request, EsConfig.COMMON_OPTIONS);
            long total = response.getHits().getTotalHits().value;
            Integer totalPage = (int) Math.ceil((double) total / limit);
            map.put("currPage", start + 1);
            map.put("pageSize", limit);
            map.put("totalPage", totalPage);
            map.put("totalCount", total);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                Map<String, HighlightField> highlightFieldsMap = hit.getHighlightFields();
                sourceAsMap = getHighLightMap(sourceAsMap, highlightFieldsMap);

                list.add(sourceAsMap);
            }
            map.put("data", list);
            return map;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    //ES提供了多种多样的聚合查询,
    public void heightAvgMain(String[] args) {
        SearchRequest request = new SearchRequest();
        request.indices(CLASSIFICATION_OF_DISEASES);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //按照名字聚合
        builder.aggregation(AggregationBuilders.terms("agg").field("name.keyword").size(10));
        //按照平均身高聚合
        builder.aggregation(AggregationBuilders.avg("heightAvg").field("height"));
        request.source(builder);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> mapAgg = new HashMap<>();
        try {
            SearchResponse response = client.search(request, EsConfig.COMMON_OPTIONS);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                list.add(sourceAsMap);
            }
            /**
             * 获取聚合信息
             */
            Aggregations aggregations = response.getAggregations();
            Terms terms = aggregations.get("agg");
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String keyAsString = bucket.getKeyAsString();
                long docCount = bucket.getDocCount();
                mapAgg.put(keyAsString, docCount);
            }
            //获取平均值
            Avg avg = aggregations.get("heightAvg");
            map.put("mapAgg", mapAgg);
            map.put("avg", avg.getValue());
            map.put("result", list);
            //return R.ok("查询成功!").put("result", map);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值