我正在尝试为每个聊天室获取最近用户消息的数组。但在我的版本中,我只得到所有聊天发送的消息数组。
func (r *Mongo) findLastMessages(ctx context.Context, chatIds []string) ([]*Message, error) {
if len(chatIds) == 0 {
return nil, nil
}
query := bson.M{"chat_id": bson.M{"$in": chatIds}}
cursor, err := r.colMessage.Find(ctx, query, nil)
if err != nil {
return nil, err
}
var messages []*Message
if err = cursor.All(ctx, &messages); err != nil {
return nil, err
}
err = cursor.Close(ctx)
if err != nil {
return nil, ErrInternal
}
return messages, err
}
是否有任何方法可以过滤样本,以便我只获得每个聊天的最后一条消息?
和
也许你应该使用聚合来达到这样的目的?如果是这样,是循环查找更好还是使用聚合更好?
假设通过"last"你指的是时间戳最近的那个,我有两种方法。
如果在chat_id:1, timestamp:1上有一个索引
-
查找匹配的单个chat_it,按时间戳降序排序,限制为1。对于1:1的扫描返回比例,这将只需要加载所需的文档。对每个聊天
重复 -
聚合一次匹配聊天数组,按时间戳排序,然后按chat_id分组,只从每个消息中选择第一条消息。这将需要从每个聊天中加载许多消息。但是,此方法将在一个操作中返回所有文档,并使用一个网络往返。
哪种方法更适合您取决于:
- 网络往返有多贵
- 由于扫描所有额外文档的资源开销,将有多少延迟
- 查询运行的频率
- 查询将同时运行多少个实例