SpringBoot集成Mongodb文档数据库

添加Maven依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

配置Mongodb连接信息

yaml 复制代码
spring:
  data:
    mongodb:
      host: 10.30.29.246
      port: 16030
      authenticationDatabase: admin # 登录用户的认证库
      database: nrdt
      username: admin
      password: QAZqaz@123321

通用服务(动态集合数据)

以下代码实现主要针对集合名称和字段都是未知的情况

java 复制代码
@Slf4j
@Component
public class MongodbService {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 新增集合(表)
     *
     * @param collName
     */
    public void addCollection(String collName) {
        Assert.notEmpty(collName, "collName");
        boolean bol = mongoTemplate.collectionExists(collName);
        if (!bol) {
            mongoTemplate.createCollection(collName);
        }
    }

    /**
     * 删除集合(表)
     *
     * @param collName
     */
    public void dropCollection(String collName) {
        Assert.notEmpty(collName, "collName");
        boolean bol = mongoTemplate.collectionExists(collName);
        if (bol) {
            mongoTemplate.dropCollection(collName);
        }
    }

    /**
     * 清空集合数据
     *
     * @param collName
     */
    public void clearCollection(String collName) {
        Assert.notEmpty(collName, "collName");
        boolean bol = mongoTemplate.collectionExists(collName);
        if (bol) {
            mongoTemplate.remove(new Query(), collName);
        }
    }

    /**
     * 修改字段名称
     *
     * @param collName
     * @param oldName
     * @param newName
     * @return
     */
    public boolean editField(String collName, String oldName, String newName) {
        Assert.notEmpty(collName, "collName");
        Assert.notEmpty(oldName, "oldName");
        Assert.notEmpty(newName, "newName");
        Query query = new Query();
        Update update = new Update();
        update.rename(oldName, newName);
        UpdateResult result = mongoTemplate.updateMulti(query, update, collName);
        return result.wasAcknowledged();
    }

    /**
     * 删除指定列
     *
     * @param collName
     * @param field
     */
    public boolean dropField(String collName, String field) {
        Assert.notEmpty(collName, "collName");
        Assert.notEmpty(field, "field");
        Query query = new Query();
        Update update = new Update();
        update.unset(field);
        UpdateResult result = mongoTemplate.updateMulti(query, update, collName);
        return result.wasAcknowledged();
    }

    /**
     * 新增字段
     *
     * @param collName
     * @param field
     * @return
     */
    public boolean addField(String collName, String field) {
        Assert.notEmpty(collName, "collName");
        Assert.notEmpty(field, "field");
        Query query = new Query();
        query.fields().include(field);
        boolean bol = mongoTemplate.exists(query, collName);
        if(!bol){
            Update update = new Update();
            update.set(field, 0.00d);
            UpdateResult result = mongoTemplate.updateMulti(query, update, collName);
            return result.wasAcknowledged();
        }
        return false;
    }

    /**
     * 新增多个字段
     *
     * @param collName
     * @param fields
     * @return
     */
    public boolean addFields(String collName, List<String> fields) {
        Assert.notEmpty(collName, "collName");
        Assert.notNull(fields, "fields");
        Update update = new Update();
        boolean status = false;
        for (String field : fields) {
            Query query = new Query();
            query.fields().include(field);
            boolean bol = mongoTemplate.exists(query, collName);
            if(!bol){
                update.set(field, 0.00d);
                status = true;
            }
        }
        if(status){
            UpdateResult result = mongoTemplate.updateMulti(new Query(), update, collName);
            return result.wasAcknowledged();
        } else {
            return false;
        }
    }

    /**
     * 批量新增行数据
     *
     * @param collName
     * @param jsonArray
     */
    public void insert(String collName, JSONArray jsonArray) {
        Assert.notEmpty(collName, "collName");
        Assert.notNull(jsonArray, "jsonArray");
        mongoTemplate.insert(jsonArray, collName);
    }

    /**
     * 批量插入
     * insert: 可以一次性插入一整个列表,不允许插入已存在的主键
     * save:   需要遍历列表,进行一条一条的数据插入,主键存在则是修改
     * @param collName
     * @param list
     */
    public void insert(String collName, List<Document> list) {
        Assert.notEmpty(collName, "collName");
        Assert.notNull(list, "list");
        mongoTemplate.insert(list, collName);
    }

    /**
     * 修改行数据
     *
     * @param collName
     */
    public void edit(String collName, JSONObject jsonObject) {
        Assert.notEmpty(collName, "collName");
        Assert.notNull(jsonObject, "jsonObject");
        mongoTemplate.save(jsonObject, collName);
    }

    /**
     * 删除行数据
     *
     * @param collName
     */
    public boolean remove(String collName, String[] ids) {
        Assert.notEmpty(collName, "collName");
        Assert.notNull(ids, "ids");
        Query query = new Query(Criteria.where(MongoConstants.ID_COLUMN).in(ids));
        DeleteResult result = mongoTemplate.remove(query, collName);
        return result.wasAcknowledged();
    }

    /**
     * 抽样查询
     * @param search
     * @return
     */
    public List<Document> getListSample(SearchVo search){
        List<AggregationOperation> list = new ArrayList<>();
        list.add(Aggregation.sample(search.getSampleSize()));
        if(StrUtil.isNotEmpty(search.getColumns())){
            list.add(Aggregation.project(search.getColumns().split(",")));
        }
        Aggregation aggregation = Aggregation.newAggregation(list);
        return mongoTemplate.aggregate(aggregation, search.getCollName(), Document.class).getMappedResults();
    }

    /**
     * 查询样本时间的上下限
     * @param collName
     * @return
     */
    public Map<String, Object> getTimes(String collName){
        long startTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<>();
        Assert.notEmpty(collName, "collName");
        List<AggregationOperation> list = new ArrayList<>();
        list.add(Aggregation.project(MongoConstants.TIME_COLUMN));
        list.add(Aggregation.group().min(MongoConstants.TIME_COLUMN).as("minTime").max(MongoConstants.TIME_COLUMN).as("maxTime"));
        Aggregation aggregation = Aggregation.newAggregation(list);
        Document doc = mongoTemplate.aggregate(aggregation, collName, Document.class).getRawResults();
        if(doc != null){
            if(Convert.toInt(doc.get("ok")) == 1){
                List<Document> results =  doc.get("results", List.class);
                if(results != null && results.size() > 0){
                    Document obj = results.get(0);
                    if(obj != null){
                        map.put("minTime", obj.getLong("minTime"));
                        map.put("maxTime", obj.getLong("maxTime"));
                    }
                }
            }
        }
        if(CollUtil.isEmpty(map)){
            map.put("minTime", null);
            map.put("maxTime", null);
        }
        log.info("查询样本上下限时间,耗时:{}秒", (System.currentTimeMillis() - startTime)/1000);
        return map;
    }
    /**
     * 分页查询表数据
     *
     * @param search
     * @return
     */
    public TableDataInfo getPage(SearchInput search) {
        List<JSONObject> list = new ArrayList<>();
        Query query = getQuery(search);
        long count = mongoTemplate.count(query, search.getCollName());
        if (count > 0L) {
            if (StrUtil.isEmpty(search.getSort())) {
                // 默认根据时间排序
                search.setSort(MongoConstants.TIME_COLUMN);
            }
            // 分页:跳过前skip个文档,返回接下来的pageSize个文档
            int skip = (search.getPageNum() - 1) * search.getPageSize();
            query = query.with(Sort.by(search.getSort()).ascending()).skip(skip).limit(search.getPageSize());
            list = mongoTemplate.find(query, JSONObject.class, search.getCollName());
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(count);
        return rspData;
    }

    /**
     * 根据条件查询数据量
     *
     * @param search
     * @return
     */
    public long getCount(SearchInput search) {
        Query query = getQuery(search);
        return mongoTemplate.count(query, search.getCollName());
    }

    /**
     * 分页查询集合的数据
     *
     * @param search
     * @return
     */
    public List<Document> getListDoc(SearchInput search) {
        Query query = getQuery(search);
        if (StrUtil.isNotEmpty(search.getSort())) {
            query = query.with(Sort.by(search.getSort()).ascending());
        }
        int skip = (search.getPageNum() - 1) * search.getPageSize();
        query = query.skip(skip).limit(search.getPageSize());
        return mongoTemplate.find(query, Document.class , search.getCollName());
    }

    /**
     * 随机查询一条数据
     * @param collName
     * @return
     */
    public JSONObject getOne(String collName){
        Query query = new Query();
        query = query.limit(1);
        return mongoTemplate.findOne(query, JSONObject.class, collName);
    }

    public Query getQuery(SearchInput search) {
        Criteria criteria = new Criteria();
        List<Criteria> criteriaList = new ArrayList<>();
        if (StrUtil.isNotEmpty(search.getBeginTime())) {
            criteriaList.add(Criteria.where(MongoConstants.TIME_COLUMN).gte(Convert.toLong(search.getBeginTime())));
        }
        if (StrUtil.isNotEmpty(search.getEndTime())) {
            criteriaList.add(Criteria.where(MongoConstants.TIME_COLUMN).lte(Convert.toLong(search.getEndTime())));
        }
        if (criteriaList.size() > 0) {
            criteria.andOperator(criteriaList);
        }
        Query query = new Query(criteria);
        if (StrUtil.isNotEmpty(search.getColumns())) {
            query.fields().include(search.getColumns().split(","));
        }
        if(StrUtil.isNotEmpty(search.getExclude())){
            query.fields().exclude(search.getExclude().split(","));
        }
        return query;
    }

    /**
     * 根据条件复制一个新的集合数据
     * @param search
     */
    // @Async("threadPoolTaskExecutor")
    public void copyCollection(SearchCopy search) {
        long startTime = System.currentTimeMillis();
        log.info("开始把集合[{}]结果输出到另一个集合[{}]...", search.getCollName(), search.getNewId());
        clearCollection(search.getNewId());
        List<AggregationOperation> list = new ArrayList<>();
        if(StrUtil.isNotEmpty(search.getColumns())){
            list.add(Aggregation.project(search.getColumns().split(",")));
        }
        if(StrUtil.isNotEmpty(search.getBeginTime())){
            list.add(Aggregation.match(new Criteria(MongoConstants.TIME_COLUMN).gte(Convert.toLong(search.getBeginTime()))));
        }
        if(StrUtil.isNotEmpty(search.getEndTime())){
            list.add(Aggregation.match(new Criteria(MongoConstants.TIME_COLUMN).lte(Convert.toLong(search.getEndTime()))));
        }
        list.add(Aggregation.out(search.getNewId()));
        Aggregation aggregation = Aggregation.newAggregation(list);
        mongoTemplate.aggregateStream(aggregation, search.getCollName(), Document.class);
        log.info("结果输出完成,耗时:{}秒", (System.currentTimeMillis() - startTime)/1000);
    }
}

MongoTemplate增强版

使用手册:https://loser.plus/

使用MyBatisPlus的方式,优雅的操作MongoDB。

这种方式是如同Mysql表结构一样,已知集合名称和字段名称,预先定义好字段类型,自动与Mongodb进行关系映射。