mongodb优化聚合和查询的方式

时间:2013-02-03 21:47:01

标签: mongodb performance data-modeling nosql

我在我的项目中使用MongoDB进行统计和数据分析。我的目标是设计数据具有最佳性能和可扩展性。

我们假设每家商店都有几家商店和一系列独特的商品。我需要查询一些有关产品的数据,计算一些基本的统计数据(仅限幕布店)。

从性能的角度来看哪种方式更好:在Shop文档和产品列表中,然后根据此文档进行查询。

或者更好的是将每个商店的所有产品单独收集,然后为该系列构建查询?


也许问题本身就是:mongodb可以通过许多文档以如此有效的方式查询一个文档的正文。


UPD 1: 现在让我们假设产品本身非常小(Id,价格,名称,数量),并且它的数量是有限的。 (所以我肯定知道每家商店不会超过1000种产品)

UPD2 还假设我不想为了查看目的而读取该数据库,仅用于统计。 (售出多少,哪个最有趣,哪些小组等等)

1 个答案:

答案 0 :(得分:2)

与所有这些问题一样,主要决定因素之一是数据规模和增长。

每家商店的数据是否超过16兆?根据商店可以拥有多少商品以及只有一件物品可以归结为多少商品,我很快就会这样做。

我的意思是想象一下产品有多少个字段:

  • 产品ID
  • 描述
  • 价格
  • 选项
  • 货币
  • 书籍说明
  • SKU
  • 条形码(或其他)

其中一些领域会很大,例如,产品的描述可能非常庞大。

然而,如果有机会这是一个非常简单的应用程序,你正在寻找一个可以完全包含在单个数据行和商店中的产品,这些产品永远不会有超过5-8,000个项目,那么你可以做得更好使用排序的子文档:

{
    _id: ObjectId(),
    shop_name: 'toys r us',
    items: [
        { p_id: ObjectId(), price: '1000000', currency: 'GBP', description: 'fkf' }
    ]
}

但是,子文档并非没有它们的价格。想象一下,你有一个只有一个子文档的文档,在10天内有100和20,1000。

持续增长的文件造成的碎片可能非常重要。这会降低您的性能。您的性能不仅会成为一个问题,而且修复碎片也不是一件好事,之后在应用程序逻辑中解决它会更加困难。

要了解有关MongoDB实际工作原理的更多信息,您可以查看此演示文稿:http://www.10gen.com/presentations/storage-engine-internals

至于查询子文档,它确实需要在MongoDBs上做一些额外的工作,但它仍然非常便宜(比多次往返便宜),只要你设置正确。

根据我上面提供的信息,我个人会选择两个系列,但我不知道你的方案的真实程度......

修改

  

UPD 1:现在让我们假设产品本身非常小(Id,价格,名称,数量),而且数量有限。 (所以我肯定知道每家商店不会超过1000种产品)

好的,所以你的文件很小,每个文件可能只有几个字节。在这种情况下,您可以在此处使用具有2个大小分配功能的子文档来修复某些碎片:http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes

这可能会创建一个高性能的操作,仍然有1到1000个子文档可能导致碎片,但是这些碎片应该在它们出现时由较小的“新”商店文档填充。

  

UPD2还假设我不想为视图目的读取该数据库,仅用于统计。 (销售量多少,最有趣的是什么,哪些群体等等)

因此,对于每个商店,使用子文档,您可以轻松获得每个商店的销售总额,如:

db.shops.aggregate([
    // Match shop id 1
    {$match: {_id: 1}},

    // unwind the products for that shop
    {$unwind: '$products'},

    // Group back up by shop id and total amount sold
    {$group: {_id: '$_id', total_sold: {$sum: '$products.sold'}}}
])

使用新的聚合框架(自2.1版开始):http://docs.mongodb.org/manual/applications/aggregation/

因此,子文档也可以像两个单独的集合一样容易查询。