MongoDB查询/建模思路

时间:2011-12-07 18:51:58

标签: c# mongodb modeling

模型

我有一个ChatRoom的集合:

ObjectId Id
ObjectId GroupId 
ObjectId LastMessageId 
List<ObjectId> Members 
bool IsEveryone

我有一个ChatMessage的集合:

ObjectId GroupId
ObjectId RoomId
ObjectId Id
ObjectId UserId
string Text
DateTime Date

背景

每个用户都是多个组的一部分。每组包含多个房间。我拥有用户所属的所有房间以及用户目前所看到的最后消息ID的数组。

想法是计算给定用户的增量:(1)从所有房间返回所有最后消息ID,以及(2)计算用户错过的聊天消息数量(新消息) )。

服务器获取用户到目前为止看到的最新消息ID(因此我可以提取消息的日期并计算用户未看到的消息的数量)。< / p>

查询

我正在寻找的是一种运行2个快速查询的方法:

  1. 返回每个房间的最新消息ID(按日期,desc)。 输入:room-id数组。 输出:[room-id]数组:[msg-id]

  2. 计算给定用户每个会议室有多少新消息(整数)。 输入:[user-id,room-id,last-message-date]的数组。 输出:[room-id]数组:[int]。请注意,我不想计算用户写的消息。

  3. 您可以帮助构建优化查询吗?我正在使用MongoDB C#10gen SDK。

    更新

    每次我现在写一条新的聊天消息时,我还会在ChatRoom上运行原子更新以保留LastMessageId。这解决了第一个查询,同时保持了完整性(读取速率&gt;写入速率)。

1 个答案:

答案 0 :(得分:2)

回答你的问题。:

1。要获得最佳性能,您需要创建正确的复合索引:

db.ChatMessage.ensureIndex({GroupId: 1, RoomId:1, Date: -1})

然后查询将是这样的:

db.ChatMessage.find({GroupId: 2, RoomId:3}).sort({"Date": -1})

如果您只需要返回{RoomId, MessageId}个对象,则可以指定以下字段:

db.ChatMessage.find({GroupId: 2, RoomId:3}, //filter messages
             {RoomId:1, _id:1}) // specify set of fields thats query should return
             .sort({"Date": -1}) // sort by date desc
             .limit(10) // take a specific number of last messagies

要确保查询使用正确的索引,您可以使用explain()方法。

2。对于您的第二个问题,我建议使用set运算符预先计算新信息的数量,而不是使用map / reduce,因为它对大数据集的工作速度很慢。或者另一个好的选择可以是incremental异步map / reduce。

根据您在房间集合中的需求,您可以拥有NumberOfNewMessagies或嵌套数组[{UserId, MessagiesCount}]。因此,当你装载房间时,你总会有许多新的信息。

顺便说一句,如果你有麻烦将mongodb shell查询转换为c#代码,请告诉我。

希望这对你有所帮助。