个人原创,注意版权
参考文档
https://docs.spring.io/spring-data/data-mongo/docs/1.7.0.RC1/reference/html/#mongodb-connectors
SpringData MongoDB: https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#
https://docs.mongodb.com/manual/core/aggregation-pipeline/
http://www.mongoing.com/docs/tutorial/query-documents.html
使用两种方式在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);