【问题标题】:Return documents that meet a Sub-query Result Set返回满足子查询结果集的文档
【发布时间】:2018-10-14 22:52:51
【问题描述】:

我正在尝试解决在 Sql Server 中需要公用表表达式或子查询的问题。

我有一个名为 Invoice_Details 的集合。每个文档都有一个 InvoiceID、CustomerID、TransactionDate 和 TransactionAmount 字段。

我要做的是取回当 TransactionAmount 聚合时不等于零的所有文档。

我正在分组如下:

   db.Invoice_Details.aggregate(
   [
     {
       $group:
         {
           _id: { InvoiceID: "$InvoiceID"},
           Balance: { $sum: "$TransactionAmount"}
         }
     },
     { $match: { Balance: { $ne: 0 } } }
   ]
)

这会产生

{
    "_id" : {
        "InvoiceID" : "234904"
    },
    "Balance" : 182.67
}

.... 数百个额外的文档,非常棒。

我现在要做的是获取聚合中返回的所有 invoice_details 文档。

在 Sql Server 中,我会重新加入公用表表达式/子查询的结果,但我不确定如何(如果?)我可以做到这一点 mongo。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可以根据"InvoiceID" 执行"$lookup" 并立即$unwind 结果,以防我们讨论的文档结果足够大,实际上可能违反 BSON 限制;

    db.Invoice_Details.aggregate([
      { "$group": {
        "_id": "$InvoiceID",
        "balance": { "$sum": "$TransactionAmount" }
      }},
      { "$match": { "balance": { "$ne": 0 } } },
      { "$lookup": {
        "from": "Invoice_Details",
        "localField": "_id",
        "foreignField": "InvoiceID",
        "as": "details"
      }},
      { "$unwind": "$details" },
      { "$replaceRoot": { "newRoot": "$details" } }
    ])
    

    理想情况下,您可以在此处使用$replaceRoot 将包含所有结果的字段简单地提升到文档根目录中。否则,如果您的 MongoDB 版本低于 3.4 并且缺少管道阶段,请使用 $project 并命名所有字段:

      { "$project": {
        "_id": "$details._id",
        "InvoiceID": "$details.InvoiceID",
        "CustomerID": "$details.CustomerID",
        "TransactionDate": "$details.TransactionDate",
        "TransactionAmount": "$details.TransactionAmount"
      }}
    

    但实际上在这里执行"$lookup" 实际上是"InvoiceID" 上的“子查询”和连接条件,只是MongoDB 以不同的顺序呈现它。所以“依次”作为“先聚合”然后加入。

    【讨论】:

    • 所以这行得通,但即使在只有 529442 个文档的集合中,它也会超时。第一部分(查找之前)运行大约 5 秒。我在这里完全采取了错误的方法,或者这是可以理解的缓慢的事情?
    • @MillinMo 在开头的InvoiceID 上添加$sort 舞台。在现实世界中,您可能首先拥有一个日期范围的$match。最重要的是不要在 Robo3T 中运行。它确实是损坏的软件,不支持 MongoDB。使用 mongo shell,因为它可以正常工作。模仿 SQL 的方法是错误的吗?几乎可以肯定,但无需重新设计,这基本上就是您所拥有的
    猜你喜欢
    • 2014-10-21
    • 2013-08-10
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    相关资源
    最近更新 更多