集合设计
父级集合 — 消息推送概览
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方式
@Test
public 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);
}