MongoDB模式devise为​​“topic – > posts”域用例

首先,我只想说我是mongoDb的新手,来自关系“哲学”,可能我对mongoDb的工作原理可能有些假设可能是错误的。 我正在开发一个简单的项目使用MEAN堆栈,这是简单的讨论系统,你有主题和post。

为了在MongoDB中对这个用例进行build模,我提出了三种方法:

  1. embedded文件

    { topicId : ObjectId, postsNr : Number, posts : [{POST},{}] }

正如我理解这个选项,因为一些缺点,post的数量可以变得很大让我们说500,000千,从数组中推拉元素可以影响性能,因为填充因子。 embedded式文档在sorting和范围查询方面比单独的集合提供更less的灵活性。 然而,对于看到使用聚合框架,“$”操作符和$切片可以sorting,更新数组中的特定post和分页post,纠正我,如果我错了。

  1. 单独collections

    { topicId : ObjectId, postsNr : Number, }

    { postId : ObjectId, topicId : ref for topicId, }

使用这样的东西给了更多的灵活性,但知道的问题困扰了我很多。 形象这个简单的情况下,用户发表post,知道我想执行不同的写入到数据库,一个插入职位收集和另一个$ inc postsNr在主题集合中。 知道MongoDb不提供交易可能会发生,我插入post,然后出现问题,postsNr不增加,知道我的数据将是不一致的 ,我所看到的是最终不会不一致,因为它会不再一致了。

这让我想,也许我使用MongoDB的一个用例不恰当,关系数据库将是一个更好的select,但是MongoDB的快速写入和性能让我觉得它可能是一个很好的问题,这个问题。

试图缓解这个问题,我想出了一个新的devise,但我不确定这是否是正确的,因为与mongo的经验不足。

  1. embedded式和独立集合的混合

    { topicId : ObjectId, postsNr : Number, recentPostsNr : Number, recentPosts : [{},{}], //Keeps the "X" recent posts, let's say 200 }

    { postId : ObjectId, topicId : ref for topicId }

在这里,我将200个最新的post存储在Topic集合中,每次有新的post出现时,它都被存储在最近的PostPosts数组中,然后我可以增加postsNr,这是primefaces操作,因为操作是在同一个集合中完成的。

知道是棘手的部分,未来的某些点需要将de recentPosts数组flush到Post集合中,这是我的意思,不用丢失数据。

每当一个新的职位进入(伪代码):

  `if (recentPostsNr >= 200){ //Now push 180 from the recentPosts array to the Posts collection with addToSet $addToSet() findAndModify() => remove 180 posts recentPosts {}, keep 20 for retrieving and alter the recentPostsNr to 20 } //Push the new post to the recentPosts array and inc the posts nr $update($inc,$push) 

使用这种技术,我得到了两个世界的好处。 我把post移动到Post的集合与$ addToSet运算符,不允许重复,所以我做了一次,并且findAndMofidy()查询执行前发生了什么错误,下一次post插入它将执行相同的操作因为recentPostsNr仍然是200,但是没有任何事情会发生,因为$ addToSet不会改变任何东西。 这一次执行findAndModify()并更新最近的邮件数组和最近的邮件数,然后插入新的post,并且增加postsNr。

就像我说过的,我没有mongo的经验来判断这是否真的有效,或者我错过了什么。 这让我觉得,在MongoDb中,如果您需要链接文档,那么这不是您的问题的最佳select,除非数据一致性不是问题。 这导致我这篇文章: http : //www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/

很抱歉,这个post很长,但也许有更多的MongoDB初学者和我一样怀疑,你的答案可以帮助消除它们。

谢谢

以前的关系思维方式很难放松。

首先讨论第三个选项(两个集合),在我看来只使用一个。 在一个文件上保留一个时间戳,如果你需要最后一个X的数量,限制sorting的查询。 有两个相同的集合是不必要的复杂性。

第二个想法,多一个“关系”也是混乱的,你将不得不做2个查询,因为在mongo缺less联接,如果你只在一个这样做,你可以保存工作。

第一个是最好的,但是我保存这个位置很难,可以用持久性时间戳来replace(再次)。 这总是保持秩序,你可以通过计算得到的位置。 另外是一个post可以有多个主题(我不知道一个主题是像一个论坛中的主题或像一个post的标签),你可以认为在保存post作为主要文件,主题在这样的领域:

 { postContent: {[...]}, timestamp: ISODATE("..."), topic/topics :[X1,X2,...] } 

并在主题中保留一个索引来提高主题search的速度。