最近在做一个消息中心功能,其中有个私信功能用了MongoDB做分表存储,要解决的问题是“获取与每个人聊天的最后一条消息”,也就是像聊天软件的会话列表一样。
例(集合名:chat_msg_2022_1):
{send_uid: 1, receive_uid: 2, session_name: 12, msg: {type: "text", body: "第一条", send_time:100, read_status: 0}},
{send_uid: 1, receive_uid: 2, session_name: 12, msg: {type: "text", body: "第二条", send_time:200, read_status: 0}},
{send_uid: 1, receive_uid: 9, session_name: 19, msg: {type: "text", body: "第三条", send_time:300, read_status: 0}}
我的ID是1,我想得和2和9聊天的最新一条记录,也就是“第二条”和“第三条”
尝试搜索“MongoDB获取每个分类最新的一条记录”没有找到答案,通过以下方式已解决!
db.chat_msg_2022_1.aggregate([
{$match: {$or: [{"send_uid": 1}, {"receive_uid": 1}]}},
{$group: {_id: "$session_name", last_msg: {$last: "$$ROOT"}}},
])
核心的是group、last、$ROOT
如果想要获取每个分组的第一条记录,把last改成first即可
另外
:
聚合后,id会覆盖成聚合的ID,比如上例的_id是session_name,不是MongoDB的ObjectId,如果需要显示原来的objectID,需要再加上replaceRoot
db.chat_msg_2022_1.aggregate([
{$match: {$or: [{"send_uid": 1}, {"receive_uid": 1}]}},
{$group: {_id: "$session_name", last_msg: {$last: "$$ROOT"}}},
{$replaceRoot: { newRoot: "$last_msg" }}
])
获取我的会话列表,同时计算我与每个人对话的未读消息数量。主要涉及到对group加条件
db.chat_msg_2022_1.aggregate([
{$match: {$or: [{"send_uid": 1}, {"receive_uid": 1}]}},
{$group: {_id: "$session_name", last_msg: {$last: "$$ROOT"}, not_read_num: {$sum: {$cond: [{"$eq": ["$msg.read_status", 0]}, 1, 0]}}}},
{$skip: 0},
{$limit: 2}
])
————————————————
版权声明:本文为CSDN博主「猴神」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/goddnss/article/details/122303222
demo
db.AppInfo.aggregate([
{$match: {$or: [{"pid": "00000000000"}]}},
{$group: {_id: "$uid", last_msg: {$last: "$$ROOT"}}},
])
MongoTemplate代码示例
uid即_id
public List<AppInfoDto> getAll() {
// 封装查询条件
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(Criteria.where("pid").is("00000000000")));
operations.add(Aggregation.group("uid").first("uid").as("id").last("$$ROOT").as("last_msg"));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<AppInfoDto> results = mongoTemplate.aggregate(aggregation, AppInfo.class, AppInfoDto.class);
return results.getMappedResults();
}
AppInfoDto
@Data
public class AppInfoDto {
private String id;
private AppInfo last_msg;
}
AppInfo
/** 用户app版本信息 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "AppInfo")
public class AppInfo {
private static final long serialVersionUID = 3194483090079894934L;
/** 手机id */
@Id
private String id;
private String uid;
/** pid */
private String pid;
/** tenantId */
private String tenantId;
/** 手机系统类型 ios android unknown */
private String os;
/** 手机系统版本 */
private String osVersion;
/** 手机品牌 */
private String brand;
/** 手机型号 */
private String type;
/** app版本 */
private String appVersion;
/** app名称 */
private String name;
/** 手机设备号 */
private String mobileDeviceId;
private Long createTime;
private Long updateTime;
}