MongoDB 带组丢失字段的管道查找

MongoDB pipeline lookup with group losing fields

我只有 2 年使用 SQL 数据库的经验和 0 年没有 SQL 数据库的经验。我正在尝试使用 mongoDB compass 聚合管道工具编写一个管道,该工具执行查找、分组、求和和排序。我正在使用 MongoDB 指南针来尝试完成此操作。另外,请分享任何可以让学习变得更容易的资源,我不太喜欢在网上找到好的、易于理解的例子,使用指南针来完成这些任务。谢谢。

我要解决的示例问题是:

哪个客户下的订单数量最多?

示例数据为:

客户Collection:

{ "_id": { "$oid": "6276ba2dd1dfd6f5bf4b4f53" },  
  "Id": "1",  
  "FirstName": "Maria",  
  "LastName": "Anders",  
  "City": "Berlin",  
  "Country": "Germany",  
  "Phone": "030-0074321"}, 
{ "_id": { "$oid": "6276ba2dd1dfd6f5bf4b4f54" },  
  "Id": "2",  
  "FirstName": "Ana",  
  "LastName": "Trujillo",  
  "City": "México D.F.",  
  "Country": "Mexico",  
  "Phone": "(5) 555-4729" }

订单Collection:

{ "_id": { "$oid": "6276ba9dd1dfd6f5bf4b501f" },  
  "Id": "1",  
  "OrderDate": "2012-07-04 00:00:00.000",  
  "OrderNumber": "542378",  
  "CustomerId": "85",  
  "TotalAmount": "440.00" },
{ "_id": { "$oid": "6276ba9dd1dfd6f5bf4b5020" },  
  "Id": "2",  
  "OrderDate": "2012-07-05 00:00:00.000",  
  "OrderNumber": "542379",  
  "CustomerId": "79",  
  "TotalAmount": "1863.40" }

我整天都在看 youtube 视频和 MongoDB 文档,但我无法理解一些事情。第一,当我执行 $group 函数时,我丢失了与该组无关的所有字段,我想保留一些字段。我想让它 return 订单最高的客户的名字。

我使用的管道如下:

[{
   $lookup: {
      from: 'Customer',
      localField: 'CustomerId',
      foreignField: 'Id',
      as: 'CustomerInfo'
 }}, {
   $project: {
      CustomerId: 1,
      CustomerInfo: 1
 }}, {
   $group: {
      _id: '$CustomerInfo.Id',
      CustomerOrderNumber: {
   $sum: 1
  }
 }}, {
   $sort: {
      CustomerOrderNumber: -1
 }}]

示例数据 return 按顺序排列:

为错误的格式道歉,仍在努力掌握发布易于理解和有用的问题的窍门。

$group 阶段,它只有 returns 文档具有 _idCustomerOrderNumber 字段,因此缺少 CustomerInfo 字段。

  1. $lookup
  2. $project - 从第一阶段开始,CustomerInfo returns 作为数组,因此将第一个文档作为文档字段而不是数组字段。
  3. $group - 按 CustomerId 分组,将文档相加为 CustomerOrderNumber,并将第一个文档作为 CustomerInfo.
  4. $project - 修饰输出文档。
  5. $setWindowsFields - $denseRank to rank the document position by CustomerOrderNumber (DESC). If there are documents with same CustomerOrderNumber, the ranking will treat them as same rank/position.
  6. $match - Select 文档 denseRankHighestOrder 为 1(最高)。
db.Order.aggregate([
  {
    $lookup: {
      from: "Customer",
      localField: "CustomerId",
      foreignField: "Id",
      as: "CustomerInfo"
    }
  },
  {
    $project: {
      CustomerId: 1,
      CustomerInfo: {
        $first: "$CustomerInfo"
      }
    }
  },
  {
    $group: {
      _id: "$CustomerInfo.Id",
      CustomerOrderNumber: {
        $sum: 1
      },
      CustomerInfo: {
        $first: "$CustomerInfo"
      }
    }
  },
  {
    $project: {
      _id: 0,
      CustomerId: "$_id",
      CustomerOrderNumber: 1,
      CustomerName: {
        $concat: [
          "$CustomerInfo.FirstName",
          " ",
          "$CustomerInfo.LastName"
        ]
      }
    }
  },
  {
    $setWindowFields: {
      sortBy: {
        CustomerOrderNumber: -1
      },
      output: {
        denseRankHighestOrder: {
          $denseRank: {}
        }
      }
    }
  },
  {
    $match: {
      denseRankHighestOrder: 1
    }
  }
])

Sample Mongo Playground


注:

$sort 阶段能够按 CustomerOrderNumber 对文档进行排序。但是如果尝试限制诸如“SELECT TOP n”这样的文档,当存在多个相同CustomerOrderNumber/rank.

的文档时,输出结果可能不正确

示例:SELECT CustomerOrderNumber 最高的 TOP 1 客户,但有 3 个客户的 CustomerOrderNumber 最高。