我正在开始一个MongoDB项目,只是为了解决问题,并且有机会学习MongoDB/NoSQL模式.它将是一个实时聊天应用程序,堆栈包括:Rails 3,Ruby 1.9.2,Devise,Mongoid/MongoDB,CarrierWave,Redis,JQuery.
我将分别处理实时聊天轮询/消息排队.不确定Node.js,APE或自定义EventMachine应用程序.但是对于Mongo,我正在考虑将它用于应用程序中的其他所有内容,特别是聊天日志和历史记录.
我的问题是如何最好地设计模式,因为我以前的经验都是使用MySQL和关系数据库模式.作为一个子问题,我们何时最好将嵌入式文档与相关文档进行对比.
该应用程序将具有:
多个帐户,有多个房间
多个房间
每个房间有多个用户
允许用户进入的房间列表
每个房间有多个用户聊天
可搜索的聊天记录每个房间和每个用户
给定聊天的可选文件附件
鉴于Mongo(至少我上次检查过)的文件限制为4MB,我不认为有一个房间集合和存储所有房间聊天,因为嵌入式文档会很好.
从我到目前为止的想法,我想做的事情如下:
帐户集合
房间的集合
每个房间都与账户有关
聊天集合中的相关文档,用于房间中的所有聊天消息
嵌入式文档列出了当前房间内的所有用户
用户的集合
嵌入式文档列出了用户当前所在的所有房间
嵌入式文档列出了允许用户进入的所有房间
聊天集合
每次聊天都与房间集合中的房间有关
每个聊天都与用户集合中的用户相关
嵌入式文档,包含有关可选上载文件附件的信
我主要担心的是,在最终看起来像一个关系模式并且我打败了目的之前,我还能走多远?肯定有比嵌入更多的相关内容.
另一个问题是,引用相关文档要比访问我所听到的嵌入式文档慢得多.
我想制作通用查询,例如:
给我一个帐户的所有房间
给我一个房间的所有聊天(或通过日期范围过滤)
给我一个特定用户的聊天记录
给我在给定房间或给定组织中的所有上传文件
等等
有关如何以可扩展的方式有效地构建模式的任何建议?感谢大家.
我认为你几乎走在正确的轨道上.我会为聊天行使用上限集合,每行包含用户ID,房间ID,时间戳和所说的内容.一旦达到上限集合的"结束",这些数据就会过期,因此如果您需要历史日志,您需要定期将数据从上限集合中复制到"日志"集合中,但是上限集合专门用于记录 - 样式应用程序,您不会删除文档,并且插入顺序很重要.在聊天的情况下,这是一个完美的匹配.
我建议的唯一其他变化是在单独的集合中维护上传.