2014-10-21 53 views
4

我正在开发一个项目,该项目记录跨多个地区的物品的价格历史记录,并且计划将这些数据存储在一个mongodb集合中。mongodb - 针对大量数据点的推荐树结构

因为我对mongodb比较陌生,所以我对很多数据的推荐文档结构感兴趣。情况如下:

我在200个左右的地区记录约90,000项物品的价格历史记录。我期望每小时记录每件商品的价格,并给出任何特定商品的2周历史记录。大约出现(90000 * 200 * 24 * 14)= 60亿个数据点,或者大约67200个数据点。清理查询将每天运行一次,以删除超过14天的记录(更具体地说,将其归档为压缩的json /文本文件)。

就我所知道的数据而言,我主要关注两件事情:1)特定地区特定商品的价格历史记录; 2)特定商品的价格历史记录遍及所有地区。

在我真正开始导入这些数据并运行基准测试之前,我希望有人能够给出一些建议,说明如何构建这个数据库以允许通过查询快速访问数据。

我正在考虑以下结构:

{ 
    _id: 1234, 
    data: [ 
     { 
      territory: "A", 
      price: 5678, 
      time: 123456789 
     }, 
     { 
      territory: "B", 
      price: 9876 
      time: 123456789 
     } 
    ] 
} 

每个项目都是自己的文件,其中每个区域/价格点在特定领土该项目。我遇到的问题是检索特定商品的价格历史记录。我相信我可以用下面的查询实现这一点:

db.collection.aggregate(
    {$unwind: "$data"}, 
    {$match: {_id: 1234, "data.territory": "B"}} 

) 

我正在考虑只是把每一个数据点自己的文档中,然后将一个指数的项目和境内的其他选择。

// Document 1 
{ 
    item: 1234, 
    territory: "A", 
    price: 5679, 
    time: 123456789 
} 
// Document 2 
{ 
    item: 1234, 
    territory: "B", 
    price: 9676, 
    time: 123456789 
} 

我只是不确定是否具有6个十亿文件用三个指标或与67200对象数组90000个文档每使用聚合会获得更好的性能。

或者也许有其他一些树结构或处理这个问题,你罚款人和MongoDB向导可以推荐?

+0

这是一个有点主观,真的应该回答,但问自己“你通过保持物品在数组中获得什么好处?”。在MongoDB中使用数组的一般想法是将相关数据以这种方式存储在一起。这意味着如果您使用单个文档并将所有或多个数组点一起读取/写入,然后使用数组。如果不是那么阵列不是最好的选择。销售订单和项目是一个很好的选择,但其他的事情可能不会。 – 2014-10-22 01:43:19

回答

2

我会将文档的结构设置为“每个固定时间间隔内给定区域内产品的价格”。整个模式的时间间隔是固定的,但不同的模式是由不同的选择产生的,对于您的应用程序来说最好的模式可能需要通过测试来决定。选择时间间隔为1小时可以得出第二个模式构思,总共约60亿个文档。你可以选择时间间隔为2周(不)。在我看来,最好的时间间隔的选择是1天,这样的文件看起来像这样

{ 
    "_id" : ObjectId(...), // could also use a combination of prod_id, terr_id, and time so you get a free unique index to look up by those 3 values 
    "prod_id" : "DEADBEEF", 
    "terr_id" : "FEEDBEAD", 
    "time" : ISODate("2014-10-22T00:00:00.000Z"), // start of the day this document contains the data for 
    "data" : [ 
     { 
      "price" : 1234321, 
      "time" : ISODate("2014-10-22T15:00:00.000Z") // start of the hour this data point is for 
     }, 
     ... 
    ] 
} 

我喜欢1天的时间间隔,因为它击中的文档数量之间一个很好的平衡(主要是因为相关的索引大小),文档大小(16MB限制,必须通过网络传输)以及便捷的退休旧文档(15天保存,每天从某一时刻的第15天开始清除)。如果你把索引放在{ "prod_id" : 1, "terr_id" :}上,那应该让你有效地完成你的两个主要查询。通过为每一天预先分配文档,您可以获得额外的奖励性能提升,以便更新到位。

根据建立MMS监控系统的经验,有关于管理像这样的时间序列数据的great blog post。我基本上从那里解除了我的想法。