消息模块的数据模型设计

文章介绍了如何在MongoDB中创建POJO映射类,包括`message`和`message_ref`集合,用于处理消息和接收状态。同时,展示了如何进行联合查询以根据接收人查询消息并按时间排序。文章还提到了避免消息重复消费的方法,利用UUID作为唯一标识。

目录

一、创建POJO映射类

1. message集合 

2. message_ref集合 

二、MongoDB的联合查询


MessageRef:保存消息接收人相关信息,接收人ID、消息已读未读、消息是否最新接收。

        在 MongoDB 里面我们不需要预先去创建集合,只要我们往 MongoDB 里面保存数据,那么相应的集合就创建出来了。


一、创建POJO映射类

        MongoDB中没有数据表的概念,而是采用集合(Collection)存储数据,每条数据就是一个文档(Document)。文档结构很好理解,其实就是我们常用的JSON,一个JSON就是一条记录。 

1. message集合 

        集合相当于MySQL中的数据表,但是没有固定的表结构。集合有什么字段,取决于保存在其中的数据。下面这张表格是 Message 集合中JSON数据的结构要求。 

        比如说小程序每隔5分钟轮询是否有新的消息,如果积压的消息太多,Java系统没有接收完消息,这时候新的轮询到来,就会产生两个消费者共同接收同一个消息的情况,这会造成数据库中添加了重复的记录,如果每条MQ消息都有唯一的UUID值,第一个消费者把消息保存到数据库,那么第二个消费者就无法再把这条消息保存到数据库,解决了消息的重复消费问题。 

创建 MessageEntity.java 类,映射 message 集合。

@Data
@Document(collection = "message")
public class MessageEntity implements Serializable {
    @Id
    private String _id;

    @Indexed(unique = true)
    private String uuid;

    @Indexed
    private Integer senderId;

    private String senderPhoto="https://static-1258386385.cos.ap-beijing.myqcloud.com/img/System.jpg";

    private String senderName;

    private String msg;

    @Indexed
    private Date sendTime;
}

2. message_ref集合 

        虽然 message 集合记录的是消息,里面有接受者ID,但是如果是群发消息,那么接受者ID是空值。这时候就需要用上 message_ref 集合来记录接收人和已读状态。 

 

创建 MessageRefEntity.java 类,映射 message_ref 集合。 

@Data
@Document(collection = "message_ref")
public class MessageRefEntity implements Serializable {
    @Id
    private String _id;

    @Indexed
    private String messageId;

    @Indexed
    private Integer receiverId;

    @Indexed
    private Boolean readFlag;

    @Indexed
    private Boolean lastFlag;
}

二、MongoDB的联合查询

        MongoDB从3.X开始支持集合的连接查询,也就相当于MySQL的表连接。我们先要向MongoDB中添加记录,于是 message 和 message_ref 两个集合就都创建出来了。 

db.message.insert( {
	_id: ObjectId("600bea9ab5bafb311f147506"),
	uuid:"bfcb7c47-5886-c528-5127-ce285bc2322a",
	senderId: 0,
	senderPhoto: "https://static-1258386385.cos.ap-beijing.myqcloud.com/img/System.jpg",
	senderName: "Emos系统",
	msg: "HelloWorld",
	sendTime: ISODate("2021-01-23T17:21:30Z") 
 } );

db.message_ref.insert( {
	_id: ObjectId("600beaf0d6310000830036f3"),
	messageId: "600bea9ab5bafb311f147506", 
	receiverId: 1,
	readFlag: false,
	lastFlag: true
} );

        执行两个集合的联合查询,根据接收人来查询消息,并且按照消息发送时间降序排列,查询前50 条记录

db.message.aggregate([
    {
        $set: {
            "id": { $toString: "$_id" }
        }
    },
    {
        $lookup:{
            from:"message_ref",
            localField:"id",
            foreignField:"messageId",
            as:"ref"
        },
    },
    {
        $match:{
            "ref.receiverId": 1
        }
    },
    {
        $sort: {
            sendTime : -1
        }
    },
    {
        $skip: 0 
    },
    { 
        $limit: 50 
    }
])
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengbo_eva

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值