我有一个包含半复杂记录的MongoDB数据库,随着集合大小的增加,我的报告查询也在苦苦挣扎。我想制作一些针对快速搜索和聚合进行优化的报告视图。以下是一种示例格式:
var record = {
fieldOne:"",
fieldTwo:"",
fieldThree:"", //There is approx 30 fields at this level
ArrayOne:[
{subItem1:""},
{subItem2:""} // There are usually about 10-15 items in this array
],
ArrayTwo:[
{subItem1:""}, //ArrayTwo items reference ArrayOne item ids for ref
{subItem2:""} // There are usually about 20-30 items in this array
],
ArrayThree:[
{subItem1:""},// ArrayThree items reference both ArrayOne and ArrayTwo items for ref
{subItem2:""},// There are usually about 200-300 items in this array
{subArray:[
{subItem1:""},
{subItem2:""} // There are usually about 5 items in this array
]}
]
};
我以前有ArrayTwo
位于ArrayOne
项内且ArrayThree
位于ArrayTwo
项内的数据,因此暗示引用父项,但报告成了噩梦具有多个嵌套级别的数组。
我在每个级别都有一个名为'fieldName'的字段,这是我们在数组中定位对象的方式。
我经常需要在查询中的数千条记录中聚合来自3个数组中任何一个的值。
我看到了两种方法。
A)。展平并纵向移动,在数据库中为ArrayThree
中的每个项目创建一条较小的记录,实际上每个复杂记录添加200条记录。我尝试了这个,并且我在5天的新数据中已经有200K记录。这样做的好处是我有可以编入索引的fieldNames。
B)。水平展平,使每个数组在单个集合记录中保持平坦。我将使用位于每个数组对象中的FieldName作为key
。这将创建一个包含200-300个字段的单个记录。这会使集合中的记录少得多,但字段将是动态的,因此无法添加索引(我知道)。
目前,我有大约300K的现有记录,我将构建此视图。如果我是垂直的,那将在数据库中放置6000万个简单记录,如果我进入水平,那么将是300K记录,每个记录200个字段,每个记录都没有索引能力。
采用这种方式的正确方法是什么?
答案 0 :(得分:0)
我倾向于坚持使用mongo哲学,并为每个不同的信息集创建单独的条目,而不是依赖于奇怪的复合对象中的引用。
6000万条记录是“很多”(但实际上并非“一吨”),而且mongodb喜欢把很多小东西扔到它上面。另一方面,你最终会得到更少的大型物体并占用更多的空间。
(*使用有线老虎后端进行压缩会使你的磁盘更进一步。)
**编辑: 我还要补充一点,你真的非常想在一天结束时使用索引,所以这是对这种方法的另一次投票。