我的第一个问题是:所有这些交互应该在同一个集合中还是应该按类型将它们分开(就像在 RDBMS 中那样)?
文档存储相对于关系数据库的最大优势正是您可以做到这一点。将所有不同的交互放入一个集合中,不要害怕为它们提供不同的字段集。
此外,我希望能够查找:
特定用户进行的所有交互
我正在考虑为用户在其文档中执行的每个交互添加一个对交互文档的手动引用,并为在每个交互文档中执行交互的用户手动引用。
请注意,拥有无限增长的文档通常不是一个好主意。MongoDB 有文档大小的上限(默认:16MB)。MongoDB 不擅长处理大型文档,因为文档完全加载到内存缓存中。当您有许多大对象时,缓存中容纳不了多少。此外,当文档增长时,有时需要将它们移动到另一个硬盘驱动器位置,这会减慢更新速度(这也是自然顺序的螺丝钉,但无论如何你都不应该依赖它)。
所有进行了特定交互的用户
您是指特定的交互实例(假设多个用户可以是一个交互的一部分)还是已经执行特定交互类型的所有用户?
在后一种情况下,我将向用户文档添加一组执行的交互类型,因为否则您将不得不执行类似连接的操作,这需要 MapReduce 或一些应用程序端的逻辑。
第一种情况,与 Sammaye 的建议相反,我建议不要使用用户集合的 _id 字段,而是使用用户名。当您在 user.username 上使用带有唯一标志的索引时,它与通过 user._id 搜索一样快,并且保证了唯一性。
原因是当您搜索特定用户的交互时,您更有可能知道用户名而不是 id。当您只有用户名并且通过 id 引用用户时,您首先必须搜索 users 集合以获取用户名的 _id,这是一个额外的数据库查询。
这当然假设您并不总是手头有 user._id。当你这样做时,你当然可以使用 _id 作为参考。