共计 771 个字符,预计需要花费 2 分钟才能阅读完成。
问题背景
为什么突然想到要记录下mongo中 $addToSet $push这两个操作符呢?因为这个问题让我在生产中踩过坑。生产中我们的系统会对每一次的事件做一次记录,就是持久化一个 timeline,有一次在跟平台方对接的时候,要查看这个timeline,发现部分单子存在记录的数量有点对不上
// Timeline在mongo中的数据结构
"timeline" : [
{
"event" : "CALLBACK", // 事件
"message": "记录的描述....", // 对事件的描述
"operatedBy": "5c78ffef12c5c1e12bd7dfc0", // 操作人
"timestamp" : 1551435773 // 10位时间戳
},
{
"event" : "CALLBACK",
"message": "记录的描述....",
"operatedBy": "5c78ffef12c5c1e12bd7dfc0",
"timestamp" : 1551435774
}
]
原因分析
查询了kafka上收到的消息,发现数量是对的,但是为什么kafka的消费者在消费消息写入数据库的数量少了,这时候才想到可能是mongo这个操作符导致,addToSet,向同一个数组中插入的应该是不重复的数据,从这个操作符的名字就能看出来,set就是一个去重的集合,所以在同一秒之内的 timeline 会存在连10位时间戳都一样的情况,而这样的数据只会被保留一个,当然换成更精确的13位时间戳这样的情况会少一些,但不能根本解决问题
Mongo操作符解释
- $addToSet :为组里唯一的值创建一个数组,去除重复的值。
- $push : 返回组内所有值的数组,不去除重复的值。
这两个操作符虽然都能完成往数组里添加数据的功能,但是$addToSet 可以强制确保集合中的元素唯一,而 push 没有这个限制,所以要根据具体需求来选择
正文完