【问题标题】:The way mongodb optimized for aggregation and queryingmongodb优化聚合查询的方式
【发布时间】:2013-01-18 14:49:05
【问题描述】:

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

假设我有几家商店和每个商店的独特产品列表。我需要查询一些关于产品的数据,计算一些基本的统计数据(仅限窗帘店)。

从性能的角度来看,哪种方式更好:在里面有一个 Shop 文档和一个产品列表,然后只根据这个文档进行查询。

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


也许是问题本身:mongodb 是否可以像通过许多文档一样高效地查询一个文档的正文。


UPD 1: 现在让我们假设产品本身非常小(Id、Price、Name、Count)并且数量有限。 (所以我确定每个店铺不会超过 1000 件产品)

UPD2 还让我们假设我不想为了查看目的而读取该数据库,只是为了统计。 (卖了多少,哪个最有趣,什么组等等)

【问题讨论】:

    标签: mongodb performance data-modeling nosql


    【解决方案1】:

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

    您每家商店的数据会超过 16 兆吗?从商店可以拥有多少商品以及可以将多少数据归因于单个商品来判断,我会非常快。

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

    • 产品编号
    • 说明
    • 价格
    • 选项
    • 货币
    • 简介
    • 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

    至于查询子文档,它确实需要在 MongoDB 端做一些额外的工作,但如果你设置正确的话,它仍然很便宜(比多次往返便宜)。

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

    编辑

    UPD 1:现在让我们假设产品本身非常小(Id、Price、Name、Count)并且数量有限。 (所以我确定每个店铺不会超过 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/

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

    【讨论】:

    • 感谢您的回答。我做了一些更新以获得更多数据。
    猜你喜欢
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 2021-05-04
    • 1970-01-01
    • 2018-02-18
    • 2010-10-23
    相关资源
    最近更新 更多