zoukankan      html  css  js  c++  java
  • SpringBoot中使用ES和MongoDB常用API

    本文主要介绍一些ES和MongoDB的API使用,请不要纠结代码上下文。

    1、调用ES接口

    使用RestHighLevelClient

    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-client</artifactId>
        <version>7.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.6.0</version>
    </dependency>
    
    spring:
        elasticsearch:
            rest:
                uris: http://localhost:9200
                username: contentdev
                password: contentdevbeta123
    

    1、条件查询+分页+排序

    //创建查询请求,“gushici”代表es的集合
    SearchRequest searchRequest = new SearchRequest("gushici");
    //构建查询条件
            SearchSourceBuilder searchSourceBuilder = buildSearchQuery(guShiCiListParam);
    //应用查询条件,固定写法
            searchRequest.source(searchSourceBuilder);
            try {
    //调用接口进行查询,RequestOptions.DEFAULT为请求选项,一般固定写成这个
                SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
                if (searchResponse.status() == RestStatus.OK) {
    //处理es查询结果
                    handleSearchResponse(result, searchResponse);
                }
            }
    //构建查询条件
    private SearchSourceBuilder buildSearchQuery(GuShiCiListParam guShiCiListParam) {
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //构建布尔查询
            BoolQueryBuilder boolQueryBuilder = buildBoolQueryBuilder(guShiCiListParam);
    //应用布尔查询,固定写法
            searchSourceBuilder.query(boolQueryBuilder);
            if (guShiCiListParam.getPageNo() != null && guShiCiListParam.getPageSize() != null) {
    //设置起始偏移量
                searchSourceBuilder.from((guShiCiListParam.getPageNo() - 1)* guShiCiListParam.getPageSize());
    //设置终止偏移量
                searchSourceBuilder.size(guShiCiListParam.getPageSize());
            }
            if (guShiCiListParam.getSortRegx() != null) {
                List<Map<String,String>> sortRegx = guShiCiListParam.getSortRegx();
                for (Map<String,String> map : sortRegx) {
                    String sortField = map.get("sortField");
                    if (StringUtils.isEmpty(sortField)) {
                        continue;
                    }
                    String sortType = map.get("sortType");
    //设置排序,new FieldSortBuilder(sortField)设置排序字段,.order设置排序类型,可以调用多次sort方法,表示多个字段排序
                    searchSourceBuilder.sort(new FieldSortBuilder(sortField).order("DESC".equals(sortType) ? SortOrder.DESC : SortOrder.ASC));
                }
            }
            return searchSourceBuilder;
        }
     
    //构建布尔查询
    private BoolQueryBuilder buildBoolQueryBuilder(GuShiCiListParam guShiCiListParam) {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            if (guShiCiListParam.getVersionId() != null) {
    //filter相当于mysql中的“and”的意思,QueryBuilders.termQuery构建一个term查询,表示某个字段等于某个值,filter可以调用多次,实现xxx and xxx and xxx的效果
                boolQueryBuilder.filter(QueryBuilders.termQuery("versionId", guShiCiListParam.getVersionId()));
            }
            if (guShiCiListParam.getCopyrightRisk() != null) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("copyrightRisk", guShiCiListParam.getCopyrightRisk()));
            }
            if (guShiCiListParam.getOffline() != null) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("offline", guShiCiListParam.getOffline()));
            }
            return boolQueryBuilder;
        }
     
    //处理es查询结果
    private void handleSearchResponse(List<GuShiCiSummaryDTO> result, SearchResponse searchResponse) {
    //获取命中的结果
            SearchHits hits = searchResponse.getHits();
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit : searchHits) {
    //获取每个结果中的字段数据
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
    //获取高亮字段信息
                Map<String,HighlightField> highlightFieldMap = hit.getHighlightFields();
                GuShiCiSummaryDTO shiCiSummaryDTO = new GuShiCiSummaryDTO();
    //获取指定字段的值
                shiCiSummaryDTO.setId((String) sourceAsMap.get("guShiCiId"));
                String author = (String) sourceAsMap.get("author");
    //获取指定字段的高亮信息
                HighlightField highlightField = highlightFieldMap.get("author");
    //获取加了高亮之后的字段内容,如本来author字段的值为“李白”,高亮以后是“<em>李</em>白”,需要用高亮以后的信息替换原始的信息
                StringBuilder c = new StringBuilder();
                if (highlightField != null) {
                    for (Text text : highlightField.getFragments()) {
                        c.append(text);
                    }
                }
                if (c.length() > 0) {
                    author = c.toString();
                }
                shiCiSummaryDTO.setAuthor(author);
        }
    

    2、统计符合条件的数据总数

    //构建查询数量请求
    CountRequest countRequest = new CountRequest(matrixGuShiCiCollection);
    //应用查询条件
            countRequest.query(buildBoolQueryBuilder(guShiCiListParam));
            try {
    //调用count接口,固定写法
                CountResponse countResponse = client.count(countRequest,RequestOptions.DEFAULT);
                if (countResponse.status() == RestStatus.OK) {
                    return countResponse.getCount();
                }
            }
    

    3、分词搜索+分页+排序+高亮

    List<GuShiCiSummaryDTO> result = new ArrayList<>();
            SearchRequest searchRequest = new SearchRequest(matrixGuShiCiCollection);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //构建MultiMatch分词查询,"title","author","gen","body"是要分词查询的字段
            MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder(searchAnalysedParam.getKeyword().trim(),"title","author","gen","body");
    //设置每个字段查询的权重
            multiMatchQueryBuilder.field("title",100).field("author",10).field("gen",10)
                    .field("body",2).analyzer("ik_smart");
            searchSourceBuilder.query(multiMatchQueryBuilder);
    //配置高亮选项,field("title")是需要高亮的字段,preTags()和postTags()用来设置高亮的首尾标签,fragmentSize设置高亮结果每个片段的字符串长度,numOfFragments设置将高亮结果分为多少个片段
            HighlightBuilder highlightBuilder = new HighlightBuilder().field("title").field("author").field("gen")
                    .field("body").preTags(searchAnalysedParam.getPreTag()).postTags(searchAnalysedParam.getPostTag()).fragmentSize(800000).numOfFragments(1);
    //应用高亮设置
            searchSourceBuilder.highlighter(highlightBuilder);
    //设置分页
            if (searchAnalysedParam.getPageNo() != null && searchAnalysedParam.getPageSize() != null) {
                searchSourceBuilder.from((searchAnalysedParam.getPageNo() - 1) * searchAnalysedParam.getPageSize());
                searchSourceBuilder.size(searchAnalysedParam.getPageSize());
            }
    //设置排序
            searchSourceBuilder.sort(new FieldSortBuilder("createTime").order(SortOrder.DESC));
            searchRequest.source(searchSourceBuilder);
            try {
                SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
                if (searchResponse.status() == RestStatus.OK) {
                    handleSearchResponse(result, searchResponse);
                }
            }
     
     
            SearchHits hits = searchResponse.getHits();
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                Map<String,HighlightField> highlightFieldMap = hit.getHighlightFields();
                GuShiCiSummaryDTO shiCiSummaryDTO = new GuShiCiSummaryDTO();
                shiCiSummaryDTO.setId((String) sourceAsMap.get("guShiCiId"));
                String author = (String) sourceAsMap.get("author");
                HighlightField highlightField = highlightFieldMap.get("author");
                StringBuilder c = new StringBuilder();
                if (highlightField != null) {
                    for (Text text : highlightField.getFragments()) {
                        c.append(text);
                    }
                }
                if (c.length() > 0) {
                    author = c.toString();
                }
            }
    

    4、模糊搜索(不分词)+分页+排序+高亮(不分词,手动处理高亮)

    SearchRequest searchRequest = new SearchRequest(matrixGuShiCiCollection);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //构建布尔查询
            BoolQueryBuilder boolQueryBuilder = buildSearchSplitKeyWordBuilder(keyword);
    //应用查询条件
            searchSourceBuilder.query(boolQueryBuilder);
    //设置分页信息
            if (pageNo != null && pageSize != null) {
                searchSourceBuilder.from((pageNo - 1)*pageSize);
                searchSourceBuilder.size(pageSize);
            }
    //设置排序信息
            searchSourceBuilder.sort(new FieldSortBuilder("createTime").order(SortOrder.DESC));
    //应用查询
            searchRequest.source(searchSourceBuilder);
            try {
    //调用查询接口
                SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
                if (searchResponse.status() == RestStatus.OK) {
    //处理查询结果
                    handleSearchResponse(result, searchResponse);
                }
                if (StringUtils.isNotEmpty(preTag) && StringUtils.isNotEmpty(postTag)) {
    //处理查询结果高亮
                    handleHighLightRegex(result,keyword,preTag,postTag);
                }
            }
     
    //构建布尔查询
    private BoolQueryBuilder buildSearchSplitKeyWordBuilder(String keyword) {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            String[] keywords = keyword.split(" ");
            for (String key:keywords){
                if (StringUtils.isEmpty(key)) {
                    continue;
                }
    //should相当于mysql中的“OR”,QueryBuilders.regexpQuery表示使用正则匹配,类似于mysql中的like,boost()设置权重,多次调用should,实现xxx OR xxx OR xxx OR xxx
                boolQueryBuilder.should(QueryBuilders.regexpQuery("title.raw",".*"+key+".*").boost(100));
                boolQueryBuilder.should(QueryBuilders.regexpQuery("author.raw",".*"+key+".*").boost(10));
                boolQueryBuilder.should(QueryBuilders.regexpQuery("gen.raw",".*"+key+".*").boost(10));
                boolQueryBuilder.should(QueryBuilders.regexpQuery("body.raw",".*"+key+".*").boost(2));
            }
            return boolQueryBuilder;
        }
     
    //处理查询结果高亮
    private void handleHighLightRegex(List<GuShiCiSummaryDTO> result,String keyword,String preTag,String postTag){
            String replacement;
            String[] keywords = keyword.split(" ");
            preTag = preTag.replaceAll(""","'");
            postTag = postTag.replaceAll(""","'");
            for (GuShiCiSummaryDTO guShiCiSummaryDTO:result){
                for (String kw : keywords) {
                    replacement = preTag + kw + postTag;
                    if (CommonUtils.stringIsNotEmpty(guShiCiSummaryDTO.getTitle())){
                        guShiCiSummaryDTO.setTitle(guShiCiSummaryDTO.getTitle().replaceAll(kw,replacement));
                    }
                    if (CommonUtils.stringIsNotEmpty(guShiCiSummaryDTO.getAuthor())){
                        guShiCiSummaryDTO.setAuthor(guShiCiSummaryDTO.getAuthor().replaceAll(kw,replacement));
                    }
                    if (CommonUtils.stringIsNotEmpty(guShiCiSummaryDTO.getGen())){
                        guShiCiSummaryDTO.setGen(guShiCiSummaryDTO.getGen().replaceAll(kw,replacement));
                    }
                    if (CommonUtils.stringIsNotEmpty(guShiCiSummaryDTO.getBody())){
                        guShiCiSummaryDTO.setBody(guShiCiSummaryDTO.getBody().replaceAll(kw,replacement));
                    }
                }
            }
        }
    

    5、查询只返回数据在ES中的id

    SearchRequest searchRequest = new SearchRequest(matrixGuShiCiCollection);
            SearchSourceBuilder searchSourceBuilder = buildSearchQuery(guShiCiListParam);
    //不获取_source字段信息,即不获取数据的所有字段信息,查询结果只包含ES的元数据,包括ES的_id字段
            searchSourceBuilder.fetchSource(false);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
    

    6、根据条件修改字段值

    //根据条件修改请求
    UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(matrixGuShiCiCollection);
    //构建查询条件
                BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                boolQueryBuilder.filter(QueryBuilders.termQuery("title",title));
                if (b) {
                    boolQueryBuilder.filter(QueryBuilders.termQuery("gradeTypeId",1));
                }
    //设置查询条件
                updateByQueryRequest.setQuery(boolQueryBuilder);
    //设置修改脚本,ctx为内置上下文,固定写法,_source为ES里的元字段,topRank为自定义的数据字段
                updateByQueryRequest.setScript(new Script("ctx._source.topRank = "+top));
    //调用修改接口
                client.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
    

    7、查询只返回指定字段

    SearchRequest searchRequest = new SearchRequest(matrixGuShiCiCollection);
            SearchSourceBuilder searchSourceBuilder = buildSearchQuery(guShiCiListParam);
    //fetchSource第一个参数表示想返回的字段,第二个参数表示不想返回的字段
            searchSourceBuilder.fetchSource(new String[] {"title","body},null);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
    

    2、调用MongoDB接口

    使用MongoTemplate

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-mongodb</artifactId>
         <version>2.1.4.RELEASE</version>
    </dependency>
    
    spring:
        data:
            mongodb:
                uri: mongodb://root:1234@localhost:3717/matrix?replicaSet=mgset-33473615
    
    //声明mongodb集合名称
    @Document("gushici")
    public class GuShiCi {
    //声明主键
        @Id
        private String id;
        /**
         * 文学体裁,1:诗歌,2:词
         */
        private String type;
        /**
         * 学段
         */
        //声明对应的mongodb字段
        @Field("grade_type_id")
        private Integer gradeTypeId;
        /**
         * 创建时间
         */
        @Field("create_time")
        private Date createTime;
        ...
    }
    @Document("bibeimingju")
    public class BiBeiMingJu {
        @Id
        private String id;
        private String content;
        private String title;
        private String author;
        ...
    }
    

    1、插入数据

    //保存单条数据,第二个参数为集合名称
    mongoTemplate.save(guShiCi,COLLECTION_BI_BEI_MING_JU);
    mongoTemplate.insert(biBeiMingJuList,COLLECTION_BI_BEI_MING_JU);
    

    2、更新数据

    Criteria criteria = Criteria.where("title").is(title);
                Query query = new Query(criteria);
    //          Query query = new Query();
    //          query.addCriteria(Criteria.where("title").is(title));
                Update update = new Update().set("topRank",top);
    //更新满足条件的第一条数据
                mongoTemplate.updateFirst(query,update,GuShiCi.class);
    //更新满足条件的所有数据
                mongoTemplate.updateMulti(query,update,GuShiCi.class);
    

    3、根据id查询数据

    GuShiCi guShiCi = mongoTemplate.findById(guShiCiId, GuShiCi.class);
    

    4、分页排序条件查询

    Criteria criteria = new Criteria();
            if (guShiCiListParam.getGradeId() != null) {
                criteria.and("gradeId").is(guShiCiListParam.getGradeId());
            }
            if (guShiCiListParam.getVersionId() != null) {
                criteria.and("versionId").is(guShiCiListParam.getVersionId());
            }
            if (guShiCiListParam.getCopyrightRisk() != null) {
                criteria.and("copyrightRisk").is(guShiCiListParam.getCopyrightRisk());
            }
            if (guShiCiListParam.getOffline() != null) {
                criteria.and("offline").is(guShiCiListParam.getOffline());
            }
            Query query = new Query(criteria);
            if (guShiCiListParam.getPageNo() != null && guShiCiListParam.getPageSize() != null) {
    //分页
                query.with(PageRequest.of(guShiCiListParam.getPageNo() - 1, guShiCiListParam.getPageSize()));
            }
            if (guShiCiListParam.getSortRegx() != null) {
                List<Map<String,String>> sortRegx = guShiCiListParam.getSortRegx();
                for (Map<String,String> map : sortRegx) {
                    String sortField = map.get("sortField");
                    if (StringUtils.isEmpty(sortField)) {
                        continue;
                    }
                    String sortType = map.get("sortType");
    //排序
                    query.with(Sort.by("DESC".equals(sortType) ? Sort.Direction.DESC : Sort.Direction.ASC, sortField));
                }
            }
            List<GuShiCi> guShiCiList = mongoTemplate.find(query,GuShiCi.class);
    

    5、统计数量

    Query query = new Query(Criteria.where("gradeTypeId").is(gradeTypeId));
    return mongoTemplate.count(query,BiBeiMingJu.class);
    
  • 相关阅读:
    常用head标签
    php自定义配置文件简单写法
    sublimeText常用插件
    addslashes,htmlspecialchars,htmlentities转换或者转义php特殊字符防止xss攻击以及sql注入
    服务器安装node全教程
    Sublime Text 3 Build 3176 License
    [转]Zend Studio 文件头和方法注释设置
    给php代码添加规范的注释phpDocumentor
    [转]php 在各种web服务器的运行模式
    .htaccess文件url重写小记
  • 原文地址:https://www.cnblogs.com/xuxiaojian/p/14408856.html
Copyright © 2011-2022 走看看