集合设计
父级集合 — 消息推送概览
MsgPushInfoVo
| 字段名 | 字段类型 | 备注 |
|---|---|---|
| _id | String | 主键 |
| userId | String | 用户ID |
| userAccount | String | 学号/教职工号 |
| userType | String | 用户类型 |
| schoolId | String | 学校代码 |
| noReadCount | String | 未读消息数量 |
| pushFlag | String | 是否开启消息推送(0:关闭,1:开启) |
| childInfoList | List |
推送信息列表 |
子级集合 — 消息推送详情
MsgPushChildInfoVo
| 字段名 | 字段类型 | 备注 |
|---|---|---|
| pushTime | String | 推送时间 |
| pushType | String | 推送类型: 人工推送,自动推送 |
| content | String | 推送内容 |
| knowLibId | String | AI问题所属知识库分类ID |
| knowLibName | String | AI问题所属知识库分类名称 |
| question | String | AI问题 |
| answer | String | AI回复JSON串 |
| answerCode | String | AI场景代码 |
| readStatus | String | 已读状态(0:未读,1:已读) |
| updateStatus | String | 数据更新状态(1:已更新, 0:未更新) |
分页查询实现——原生实现
db.msgPushInfo.find({"schoolId": "LIANYI", "userAccount": "student"},{"_id": 1}).pretty();db.msgPushInfo.aggregate([{$match: {"_id": ObjectId("5eeacaa0edca59111d0d2a81")}},{$project: {"childInfoList" : 1, "_id": 0}},{$unwind: "$childInfoList"},{$match : { "childInfoList.updateStatus" : "1", "childInfoList.answerCode" : { $ne :"noData" }}},{$sort: {"childInfoList.pushTime": -1}},{$skip: 0},{$limit: 10}]).pretty();aggregate: mongodb的聚合(aggregate)使用的是管道(pipeline)的模式,上一个阶段的处理的结果做为下一个阶段的输入- {$match:{"_id": ObjectId("5eeacaa0edca59111d0d2a81")}}匹配主键为5eeacaa0edca59111d0d2a81的记录,数据导入时未设置主键,该主键默认由mongodb自动生成,需要先查询主文档获得- {$project: {"childInfoList": 1, "_id": 0}}设置投影,只显示childInfoList字段- {$unwind: "$childInfoList"}将childInfoList字段结果集展开- {$sort: {"childInfoList.pushTime": -1}}按照推送时间倒序排序- {$skip: 0}分页参数,第一页, 第N页取值 (N-1)- {$limit: 10}单页条数
分页查询实现——MongoTemplate方式
@Testpublic void mongoPage() {Document queryObject = new Document();queryObject.put("schoolId","LIANYI");queryObject.put("userAccount","student");Document fieldObject = new Document();fieldObject.put("_id",true);Query query = new BasicQuery(queryObject, fieldObject);Map<String, ObjectId> findMap = mongoTemplate.findOne(query, Map.class, "msgPushInfo");ObjectId _id = findMap.get("_id");// AggregationOperation matchOperation = Aggregation.match(Criteria.where("schoolId").is("LIANYI").and("userAccount").is("student"));// 匹配指定主键的记录(match:搜索条件criteria)AggregationOperation matchOperation = Aggregation.match(Criteria.where("_id").is(_id));// 要查询的字段信息(project:列出所有本次查询的字段,包括查询条件的字段和需要搜索的字段)AggregationOperation projectOperation = Aggregation.project("childInfoList");// 对查询的字段展开详情信息(unwind:某一个字段是集合,将该字段分解成数组)AggregationOperation unwindOperation = Aggregation.unwind("childInfoList");// 匹配 更更新AI回答,且正确回复的数据(updateStatus=1, answerCode != noData)AggregationOperation match2Operation = Aggregation.match(Criteria.where("childInfoList.updateStatus").is("1").and("childInfoList.answerCode").ne("noData"));// 排序AggregationOperation sortOperation = Aggregation.sort(Sort.Direction.DESC, "childInfoList.pushTime");// 页码AggregationOperation skipOperation = Aggregation.skip(0L);// 每页条数AggregationOperation limitOperation = Aggregation.limit(10L);Aggregation aggregation = Aggregation.newAggregation(matchOperation, projectOperation, unwindOperation, sortOperation, skipOperation, limitOperation);AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "msgPushInfo", Map.class);List<Map> batch = results.getMappedResults();List<MsgPushChildInfoVo> list = batch.stream().map(a -> JSON.parseObject(JSON.toJSONString(a.get("childInfoList")), MsgPushChildInfoVo.class)).collect(Collectors.toList());System.out.println(list);}
