Mongo - 什么是最佳设计:存储菜单文档或菜单项文档?

时间:2014-03-27 08:52:36

标签: mongodb database-design

我想在Mongo中存储网站菜单以导航我的CMS,但由于我是Mongo的新手和文档的概念,我想弄清楚什么是最好的:

a)我应该存储包含儿童和有更多孩子的菜单文件,或者 b)我应该使用parent_id和child_ids存储菜单项文档吗?

两者似乎都有好处,因为在案例A中,一次加载整个菜单是正常的,因为您需要显示所有内容,但B可能更容易更新单个项目?

我正在使用Spring数据mongo。

PS:如果我以错误的方式提出这个问题,请告诉我。我相信这个问题可以扩展到任何一般的亲子关系,但我找不到合适的词语。

2 个答案:

答案 0 :(得分:2)

由于菜单通常非常小(我希望不到16MB),因此嵌入式表单应该能为您提供最佳性能:

{
   "topItem1": [
       { "name": "item1", "link": "linkValue" },
       { "name": "item2", "link": "linkValue" }
   ],

   "topItem2": [
       { "name": "item1", "link": "linkValue" },
       { "name": "item2", "link": "linkValue" }
       { 
           "name": "sub-menu", 
           "type": "sub", 
           "items": [
               { "name": "item1", "link": "linkValue" },
               { "name": "item2", "link": "linkValue" }
           } 
       }
   ]
}

唯一可能的问题是更新嵌套数组中的内容,因为MngoDB只能"匹配" 第一个找到的数组索引。有关此内容,请参阅positional $操作员文档。

但是只要你知道这些位置,那么这应该不是问题,使用"点符号"概念:

db.menu.update({}, {
    "$set": {
        "topItem2.2.items.1": { "name": "item3", "link": "linkValue" }
    }
})

但一般添加应该很简单:

db.menu.update(
    { "topItem2.name": "sub-menu" }, 
    {
        "$push": {
            "topItem2.2.items": { "name": "item4", "link": "linkValue" }
        }
    }
)

这是关于如何使用继承嵌入式结构而不是关联" parent"的观点。和孩子"项目

答案 1 :(得分:0)

经过长时间的艰苦思考,我相信我会用:

{
    _id: {},
    submenu1: [
        {label: "Whatever", url: "http://localhost/whatever"}
    ]
}

我考虑过使用带有ID的相关文档都放在一个集合中,但是你必须拍摄多个查询以获得父级及其范围,甚至可能是子子范围。使用此结构,您只有一个查询。

此结构并非绝对可靠,但如果您定期更改菜单项,则可能会开始注意到碎片。您可以使用powerof2sizes分配来解决此问题:http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes

但是,是的,通过仔细规划,您应该能够为每个父菜单项使用一个单独的文档