2012-11-14 44 views
0

寻找设置MongoDB模式的一些指导。这里是场景:用于JSON订阅源的MongoDB模式

我正在为人们创建一个保存书签功能。在数据库中,我需要存储的是用户名,标题和链接。由此,我需要创建一个输出JSON并查询特定书签或一个人的整个提要的服务。从实施和绩效的角度来看,这两个机构中的哪一个更有意义?

A)每个书签是自己的对象:

{ 
    "_id": ObjectId("abcd1234"), 
    "username": "Choy", 
    "title": "This is my first link", 
    "url": "http://www.google.com" 
}, 
{ 
    "_id": ObjectId("abcd1234"), 
    "username": "Choy", 
    "title": "This is my second link", 
    "url": "http://www.bing.com" 
} 

B)每个用户都有自己的对象:

{ 
    "_id": "Choy", 
    "bookmarks": { 
     "abcd1234": { 
      "title": "This is my first link", 
      "url": "http://www.google.com" 
     }, 
     "abcd12345": { 
      "title": "This is my second link", 
      "url": "http://www.bing.com" 
     } 
    } 
} 

最初(A)更有意义对我来说,因为我可以很容易地查询特定的书签,更新并移除它。但从应用程序的角度来看,(B)会更容易,当我想列出一个人的所有书签,因为我可以在_id上做一个findOne(username),而不必在做一个find(username)后迭代每个记录并转换为一个数组,然后JSON(我相信这是一点内存密集型)。另一方面,在(B)中增加一个新的书签将会是一个额外的步骤,因为我必须得到记录,将一个新的书签放入其中,然后保存。

回答

3

当你在MongoDB中有一个has-a关系时,通常是将数据嵌入到拥有它的对象中的最佳决定。

您的目标是用尽可能少的搜索来满足用户的需求,因为每个文档查找都需要花费时间。如果您不需要用户的所有书签,但只需要特定的书签,则可以始终使用use the dot notation to reach into objectsretrieve subsets of fields

当您删除或重命名用户时,聚合而不是关系也很有用。 MongoDB不能像SQL数据库那样自动级联,所以在这种情况下你必须自己处理任何孤立的数据。但是,当用户文档是独立的时候,这不会是一个问题。

所以我会建议你去解决方案b)

+0

谢谢,这是有道理的。 一个跟进问题。我编辑了我的原始(B)示例,以便每个书签都有自己的密钥,而不是列在列表中。原因是我可以像你说的那样使用点符号来更新/删除书签。我如何使用mongoId()为每个书签创建一个唯一的密钥?我可以将任何字符串传递给mongoId()吗?如果我每次都传递相同的字符串,那么mongoId()仍然是唯一的吗? – Choy

+0

我不使用mongoid。但是你可以继续使用数组。 [[位置运算符]](http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator)引用触发查找查询的数组条目。 – Philipp

+0

顺便说一下,当您嵌套数组时,不能使用位置运算符。但有一个开放的bugtracker问题:https://jira.mongodb.org/browse/SERVER-831 – Philipp