【转载】MongoDB获取每个分类最新一条完整记录(会话列表、每个班级成绩最高的一名学生....)

最近在做一个消息中心功能,其中有个私信功能用了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 getAll() {
        // 封装查询条件
        List 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 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;
}

你可能感兴趣的:(【转载】MongoDB获取每个分类最新一条完整记录(会话列表、每个班级成绩最高的一名学生....))