医院无预约日期如何存入MongoDB?附聚合查询代码
如何在MongoDB中补存无预约的日期记录
针对你的问题——数据库中仅存储了有预约的日期(7.24、7.25),无预约的7.26未存入,这里提供两种可行方案:
方案一:主动插入缺失日期的空记录
如果需要永久保存无预约日期的记录,按以下步骤操作:
- 生成目标日期范围的所有日期
用Java代码遍历生成指定时间范围内的所有日期(比如最近30天):List<LocalDate> dateRange = new ArrayList<>(); LocalDate endDate = LocalDate.now(); LocalDate startDate = endDate.minusDays(30); for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) { dateRange.add(date); } - 查询数据库中已存在的日期
从目标集合中提取当前医院已有的预约日期:Query query = new Query(); query.addCriteria(hospCriteria); query.addCriteria(dateCriteria); query.fields().include("AppointmentDate"); List<Document> existingDates = mongoTemplate.find(query, Document.class, "your_collection_name"); Set<LocalDate> existingDateSet = existingDates.stream() .map(doc -> doc.getDate("AppointmentDate").toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) .collect(Collectors.toSet()); - 插入缺失日期的空记录
遍历日期列表,将不在现有集合中的日期插入数据库,字段需匹配集合结构:for (LocalDate date : dateRange) { if (!existingDateSet.contains(date)) { Document emptyApp = new Document(); emptyApp.put("Hospital_clinic", Collections.singletonMap("id", hospitalId)); emptyApp.put("AppointmentDate", Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant())); emptyApp.put("AppointmentType", "IPD"); emptyApp.put("appointmentStatus", "Active"); // 可根据业务调整为"Empty"标识空记录 mongoTemplate.insert(emptyApp, "your_collection_name"); } }
方案二:通过聚合管道补全缺失日期(查询时生成,可选存入)
如果不需要永久存储空记录,仅需查询结果包含所有日期,可修改聚合管道生成连续日期并左连接现有数据,自动补0:
修改你的聚合代码,加入日期生成和左连接逻辑:
// 生成连续日期序列的自定义聚合阶段 AggregationOperation generateDateRange = context -> { Date start = (Date) dateCriteria.getCriteriaObject().get("AppointmentDate").get("$gte"); Date end = (Date) dateCriteria.getCriteriaObject().get("AppointmentDate").get("$lte"); long dayMs = 24 * 60 * 60 * 1000; long daysDiff = (end.getTime() - start.getTime()) / dayMs + 1; return new Document("$addFields", new Document("dates", new Document("$map", new Document("input", new Document("$range", Arrays.asList(0, daysDiff))) .append("as", "offset") .append("in", new Document("$dateAdd", new Document("startDate", start) .append("unit", "day") .append("amount", "$$offset") )) ) ) ); }; // 拆分日期序列为单独文档 AggregationOperation unwindDates = Aggregation.unwind("dates"); // 左连接现有预约统计数据 AggregationOperation lookupAppointments = Aggregation.lookup( "your_collection_name", "dates", "AppointmentDate", "appointmentStats" ); // 处理左连接结果,空记录补0 AggregationOperation projectWithFill = Aggregation.project() .and("dates").as("AppointmentDate") .and(new Document("$ifNull", Arrays.asList(new Document("$arrayElemAt", Arrays.asList("appointmentStats.ipdCount", 0)), 0))).as("ipdCount"); // 构建完整聚合管道 Aggregation aggregation = newAggregation( // 生成包含日期范围的基础文档 Aggregation.match(Criteria.where("_id").exists(false)), generateDateRange, unwindDates, lookupAppointments, projectWithFill, // 过滤目标医院和有效IPD预约 Aggregation.match(hospCriteria), Aggregation.match(ipdCriteria) ); // 执行聚合获取完整结果 List<Document> fullResults = mongoTemplate.aggregate(aggregation, "your_collection_name", Document.class).getMappedResults(); // 若需要将结果存入数据库,直接遍历保存 for (Document result : fullResults) { mongoTemplate.save(result, "your_collection_name"); }
两种方案对比
- 方案一:永久存储空记录,后续查询更高效,但会增加数据库存储量。
- 方案二:仅在查询时生成完整日期序列,节省存储,但每次查询需要额外的日期生成逻辑。
内容的提问来源于stack exchange,提问作者Anubhi
相关产品推荐
相关产品推荐

