MongoDB使用总结

个人原创,注意版权

参考文档

使用两种方式在Java(Springboot)程序操作MongoDB

导入依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

第一种:使用MongoTemplate

    //保存
    public void insert(User object,String collectionName) {
        mongoTemplate.save(object, collectionName);
    }
 
    //查询一条
    public User findOne(Map<String,Object> params,String collectionName) {
         return mongoTemplate.findOne(new Query(Criteria.where("id").is(params.get("id"))), User.class,collectionName);  
    }
 
    //查询多条
    public List<User> findAll(Map<String,Object> params,String collectionName) {
        List<User> result = mongoTemplate.find(new Query(Criteria.where("age").lt(params.get("maxAge"))), User.class,collectionName);
        return result;
    }
 
    //修改
    public void update(Map<String,Object> params,String collectionName) {
        mongoTemplate.upsert(new Query(Criteria.where("id").is(params.get("id"))), new Update().set("name", params.get("name")), User.class,collectionName);
    }
 
    //新增集合
    public void createCollection(String name) {
        mongoTemplate.createCollection(name);
    }
 
 
    //删除
    public void remove(Map<String, Object> params,String collectionName) {
        mongoTemplate.remove(new Query(Criteria.where("id").is(params.get("id"))),User.class,collectionName);
    }
 

第二种:extends MongoRepository<实体,主键>

@Repository
public interface WaterRepository extends MongoRepository<Water,String> {
    //支持原生shell查询,fields指定返回列,1代表返回  0不返回
    @Query(value="{ 'Ts':{$lt:?0,$gt:?1}}",fields="{ 'Ts' : 1, 'SN' : 1, '_id' : 0}")
    List<Water> selectByWq(Long max,Long min);
   //分页查询
    @Query(value="{ 'Ts':{$lt:?0,$gt:?1}}",fields="{ 'Ts' : 1, 'SN' : 1}")
    Page<Water> selectByWqPage(Long max, Long min, Pageable pageable);
   //查询内嵌文档
    @Query(value="{ 'WQ.PH': ?0}")
    List<Water> selectByWqPh(Integer in);
}

调用
@RunWith(SpringRunner.class)
@SpringBootTest
public class WaterRepositoryTest {

@Resource
private WaterRepository waterRepository;

@Test
public void get(){

//根据id查询
Optional<Water> byId = waterRepository.findById("5ce2557fea42c90f88c75093");
System.err.println("$$$$$$$$$$$$$$$$$$$byId:"+byId);

//查询Ts>1557231820L Ts<1557231825L的数据
List<Water> byWq = waterRepository.selectByWq(1557231825L, 1557231820L);
byWq.stream().forEach(System.err::println);

//分页查询Ts>1557231820L Ts<1557231825L的数据
PageRequest pageRequest = PageRequest.of(0,2);
Page<Water> waters = waterRepository.selectByWqPage(1557231825L, 1557231820L, pageRequest);
waters.stream().forEach(System.err::println);

//查询内嵌文档WQ.PH=10的数据
List<Water> waters1 = waterRepository.selectByWqPh(10);
waters1.stream().forEach(System.err::println);
  }
}
 

自定义主键

@Component
@AllArgsConstructor
public class SaveMongoEventListener extends AbstractMongoEventListener<Object> {

    @Override
    public void onBeforeConvert(BeforeConvertEvent<Object> event) {
        final Object source = event.getSource();
        if (source != null) {
            ReflectionUtils.doWithFields(source.getClass(), field -> {
                ReflectionUtils.makeAccessible(field);
                if (field.isAnnotationPresent(ChiticMongoId.class)) {
                    Object o = field.get(source);
                    if (null == o || o.toString().equals("0")) {
                        //HubIdUtil.id(): 主键的生成规则
                        field.set(source, HubIdUtil.id());
                    }
                }
            });
        }
    }

}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ChiticMongoId {
}



@Data
@Document(collection = "data_deve_history")
public class DataDeveHistory {

    @Id
    @ChiticMongoId
    @Field("_id")
    private Long id;
}

 MongoDB的 聚合管道(aggregate)  分组查询

/**
     * 当日总供水量
     * @Author GX
     * @Date 2019/5/24 10:19
     */
    @Transactional(rollbackFor = Exception.class)
    public void dailyWaterYield(){
        //MongoDB的 聚合管道  分组查询
        Aggregation agg = Aggregation.newAggregation(
                //筛选条件: 今天
                Aggregation.match(Criteria.where(ScheduleConstant.TS_FIELD).lte(ScheduleUtil.getEndDate()).gte(ScheduleUtil.getStartDate())),
                //按照ScheduleConstant.SN_FIELD 分组 求出最大值,   as("max") 别名
                Aggregation.group(ScheduleConstant.SN_FIELD).max(ScheduleConstant.DEV_PUB_DF_FIELD).as("max"),
                //返回的字段
                Aggregation.project(ScheduleConstant.SN_FIELD,"max")
        );
        AggregationResults<Map> deve = mongoTemplate.aggregate(agg, ScheduleConstant.DEVE_COLLECTION, Map.class);
        List<Map> mappedResults = deve.getMappedResults();
        Integer sum = 0;
        for(Map<String,Integer> m : mappedResults){
            sum = sum + m.get("max");
        }
        Long dailyWaterYield = sum.longValue();
        jdbcTemplate.update("update display_screen set daily_water_yield = ? where id = ?",new Object[]{dailyWaterYield,ScheduleConstant.ID});
        log.info(LocalDate.now() +"当日总供水量"+dailyWaterYield);
    }

 分组求和

@Transactional(rollbackFor = Exception.class)
    public void monthlyCountWater(){
        Map<String, Object> minusYears = ScheduleUtil.getMinusYears(11);
        Long startTimestamp = (Long)minusYears.get("startTimestamp");
        Long endTimestamp = ScheduleUtil.getDate();
        //MongoDB的 聚合管道  分组查询
        Aggregation agg = Aggregation.newAggregation(
                //筛选条件:
                Aggregation.match(Criteria.where(ScheduleConstant.TS_FIELD).lte(endTimestamp).gte(startTimestamp)),
                //返回需要的参数,将时间戳转为时间类型,注意时区问题new Date(28800000)
                Aggregation.project(ScheduleConstant.TS_FIELD,ScheduleConstant.DEV_PUB_DF_FIELD).andExpression("[0] + "+ScheduleConstant.TS_FIELD+"*1000",new Date(28800000)).as("dateMonth"),
                //格式化时间
                Aggregation.project(ScheduleConstant.TS_FIELD,ScheduleConstant.PUB_DF_FIELD).and("dateMonth").dateAsFormattedString("%Y-%m").as("month"),
                //按照Day分组统计,   as("sum") 别名
                Aggregation.group("month").sum(ScheduleConstant.DF_FIELD).as("sum"),
                //返回的字段
                Aggregation.project("sum").and("month").previousOperation(),
                Aggregation.sort(Sort.Direction.DESC,"month")
        );
        AggregationResults<Map> deve = mongoTemplate.aggregate(agg, ScheduleConstant.DEVE_COLLECTION, Map.class);
        List<Map> mappedResultsDeve = deve.getMappedResults();
        try {
            String data = objectMapper.writeValueAsString(mappedResultsDeve);
            jdbcTemplate.update("update display_screen set monthly_count_water = ? where id = ?",new Object[]{data,ScheduleConstant.ID});
            log.info("一年内12个月(包含本月数据)的供水量:"+data);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("数据转换json出错:  {}",e);
        } finally {
        }
    }

 简单查询

        BasicQuery query = new BasicQuery("{ 'Ts' : 1557231818, 'WQ.PH' : { $gt : 8 }}");
        List<Water> result = mongoTemplate.find(query, Water.class);
        result.stream().forEach(System.err::println);

        System.err.println("----------------------------------");
        Criteria age = Criteria.where("Ts").is(1557231818L).and("WQ.PH").gt(8);
        Query query1 = new Query(age);
        List<Water> result1 = mongoTemplate.find(query1, Water.class);
        result1.stream().forEach(System.err::println);

原文地址:https://www.cnblogs.com/gaomanito/p/10898483.html