【问题标题】:optimizing a slow aggregation mongo query优化慢速聚合 mongo 查询
【发布时间】:2021-04-22 15:18:56
【问题描述】:

我有两个集合 forms4InsTrader_final(200 万份文档)和 TradeData(1300 万份文档)。 我很难理解为什么$out 没有保存聚合结果。

在以下聚合中有以下阶段:

  1. 第 1 阶段:$match 特定日期范围之间的日期。 {'pdOfRpt': {'$gte': '2004-01-01', '$lte': '2020-12-31' }}

  2. 第 2 阶段:加入 ($lookup) forms4InsTrader_finalTradeData {'from': 'aprl_test_Trade', 'localField': 'issuertradingsymbol', 'foreignField': 'ticker','as': 'string'}

  3. 第 3 阶段:$unwind 上面的“字符串”

  4. 第 4 阶段:然后匹配同一文档中的日期 {'$expr': {'$eq': [ '$pdOfRpt', '$string.Date_unmodified']}}

  5. 第 5 阶段:$unwind

  6. 第 6 阶段:使用 $project 选择我需要分析的几个字段

  7. 第 7 阶段:使用$out 保存结果

在上述所有步骤中 - 除了第 7 阶段之外,这两个集合的一切都按预期进行。但是,我想将此结果保存为单独的集合。它已经运行了三个多小时,我对大约 100 万个文档的结果有限,但我没有看到结果保存在不同的集合中。有趣的是,当我对 20000 个文档中的$limit 运行此查询时,它会在不到一分钟的时间内保存下来。我不明白为什么要用 $out 保存大约 100 万个文档的结果需要这么长时间。我在这里错过了什么?

请注意,我尝试在本地使用带有指南针和/或终端的可视化查询生成器。

完整的管道:

`db.forms4InsTrader_final.aggregate([     {         '$match': {             'pdOfRpt': {                 '$gte': '2004-01-01',                  '$lte': '2020-12-31'             }         }     }, {         '$lookup': {             'from': 'TradeData',              'localField': 'issuertradingsymbol',              'foreignField': 'ticker',              'as': 'string'         }     }, {         '$unwind': {             'path': '$string',              'includeArrayIndex': 'Date_unmodified'         }     }, {         '$match': {             '$expr': {                 '$eq': [                     '$pdOfRpt', '$string.Date_unmodified'                 ]             }         }     }, {         '$project': {             'string.Adj Close': 1,              'string.Volume': 1,              'string.Close': 1,              'string.avg_Week_Vol': 1,              'string.db.forms4InsTrader_final.aggregate([     {         '$match': {             'pdOfRpt': {                 '$gte': '2004-01-01',                  '$lte': '2020-12-31'             }         }     }, {         '$lookup': {             'from': 'TradeData',              'localField': 'issuertradingsymbol',              'foreignField': 'ticker',              'as': 'string'         }     }, {         '$unwind': {             'path': '$string',              'includeArrayIndex': 'Date_unmodified'         }     }, {         '$match': {             '$expr': {                 '$eq': [                     '$pdOfRpt', '$string.Date_unmodified'                 ]             }         }     }, {         '$project': {             'string.Adj Close': 1,              'string.Volume': 1,              'string.Close': 1,              'string.avg_Week_Vol': 1,              'string.avg_Week_Adj_Close_Price': 1,              'string.Date_unmodified': 1,              'pdOfRpt': 1,              'issuercik': 1,              'issuertradingsymbol': 1,              'reportingownerid_rptownercik': 1,              'reportingowneraddress_rptownerzipcode': 1,              'reportingownerrelationship_isdirector': 1,              'reportingownerrelationship_isofficer': 1,              'reportingownerrelationship_istenpercentowner': 1,              'reportingownerrelationship_isother': 1,              'nonderivativetransaction_securitytitle_value': 1,              'nonderivativetransaction_transactionamounts_transactionshares_value': 1,              'nonderivativetransaction_transactionamounts_transactionpricepershare_value': 1,              'nonderivativetransaction_transactionamounts_transactionacquireddisposedcode_value': 1,              'nonderivativetransaction_posttransactionamounts_sharesownedfollowingtransaction_value': 1,              'derivativetransaction_securitytitle_value': 1,              'derivativetransaction_transactionamounts_transactionshares_value': 1,              'derivativetransaction_transactionamounts_transactionpricepershare_value': 1,              'derivativetransaction_transactionamounts_transactionacquireddisposedcode_value': 1,              'derivativetransaction_ownershipnature_directorindirectownership_value': 1,              'derivativetransaction_underlyingsecurity_underlyingsecuritytitle_value': 1,              'derivativetransaction_underlyingsecurity_underlyingsecurityshares_value': 1,              'derivativetransaction_posttransactionamounts_sharesownedfollowingtransaction_value': 1         }     }, {         '$limit': 1000000     }, {         '$out': 'TestAPril20'     } ])`

Hacky 方式 - 因此指南针会生成临时集合,您可以从中导出并重新导入为单独的集合。非常低效,但是在我找到另一个解决方案之前,它让我手动操作

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    我依稀记得这是发生在我身上的解决方案,如果 allowDiskUse 能解决您的问题,请告诉我

    来自 mongodb 文档

    流水线阶段的 RAM 限制为 100 兆字节。如果一个阶段 超过此限制,MongoDB 将产生错误。为了允许 处理大型数据集,使用 allowDiskUse 选项启用 将数据写入临时文件的聚合管道阶段。

    这是一个配置标志,所以这是一个如何使用它的示例

    db.stocks.aggregate( [
          { $project : { cusip: 1, date: 1, price: 1, _id: 0 } },
          { $sort : { cusip : 1, date: 1 } }
       ],
       { allowDiskUse: true }
    )
    

    【讨论】:

    • 我认为这里的磁盘空间不是问题,显然我试过了。我认为当文档数量达到一定阈值时,它与带有输出的配置有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 2021-09-03
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多