首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MongoDB中的超分区等价

MongoDB中的超分区等价
EN

Stack Overflow用户
提问于 2022-09-22 19:04:30
回答 1查看 17关注 0票数 2

为了简洁起见,我简化了这个场景。

初步数据:

代码语言:javascript
运行
复制
| EngineerId | FirstName | LastName | BirthdateOn | CupsOfCoffee | HoursOfSleep |
| ---------- | --------- | -------- | ----------- | ------------ | ------------ |
| 1          | John      | Doe      | 1990-01-01  | 5            | 8            |
| 2          | James     | Bond     | 1990-01-01  | 1            | 6            |
| 3          | Leeroy    | Jenkins  | 2000-06-20  | 16           | 10           |
| 4          | Jane      | Doe      | 2000-06-20  | 8            | 2            |
| 5          | Lorem     | Ipsum    | 2010-12-25  | 4            | 5            |
代码语言:javascript
运行
复制
db.engineers.insertMany([
    { FirstName: 'John', LastName: 'Doe', BirthdateOn: ISODate('1990-01-01'), CupsOfCoffee: 5, HoursOfSleep: 8 },
    { FirstName: 'James', LastName: 'Bond', BirthdateOn: ISODate('1990-01-01'), CupsOfCoffee: 1, HoursOfSleep: 6 },
    { FirstName: 'Leeroy', LastName: 'Jenkins', BirthdateOn: ISODate('2000-06-20'), CupsOfCoffee: 16, HoursOfSleep: 10 },
    { FirstName: 'Jane', LastName: 'Doe', BirthdateOn: ISODate('2000-06-20'), CupsOfCoffee: 8, HoursOfSleep: 2 },
    { FirstName: 'Lorem', LastName: 'Ipsum', BirthdateOn: ISODate('2010-12-25'), CupsOfCoffee: 4, HoursOfSleep: 5 }
])

我们希望看到:

  • 工程师喝的咖啡
  • 按咖啡杯降序的行号
  • 出生日期相同的工程师的数量
  • 普通生日工程师喝咖啡的总和。
  • 有共同生日的工程师的平均睡眠时间

SQL查询是:

代码语言:javascript
运行
复制
SELECT
    FirstName,
    LastName,
    BirthdateOn,
    CupsOfCoffee,
    ROW_NUMBER() OVER (PARTITION BY BirthdateOn ORDER BY CupsOfCoffee DESC) AS 'Row Number',
    COUNT(EngineerId) OVER (PARTITION BY BirthdateOn) AS TotalEngineers,
    SUM(CupsOfCoffee) OVER (PARTITION BY BirthdateOn) AS TotalCupsOfCoffee,
    AVG(HoursOfSleep) OVER (PARTITION BY BirthdateOn) AS AvgHoursOfSleep
FROM Engineers

其结果如下:

代码语言:javascript
运行
复制
| FirstName | LastName | BirthdateOn | Row Number | CupsOfCoffee | TotalEngineers | TotalCupsOfCoffee | AvgHoursOfSleep |
| --------- | -------- | ----------- | ---------- | ------------ | -------------- | ----------------- | --------------- |
| John      | Doe      | 1990-01-01  | 1          | 5            | 2              | 6                 | 7               |
| James     | Bond     | 1990-01-01  | 2          | 1            | 2              | 6                 | 7               |
| Leeroy    | Jenkins  | 2000-06-20  | 1          | 16           | 2              | 24                | 6               |
| Jane      | Doe      | 2000-06-20  | 2          | 8            | 2              | 24                | 6               |
| Lorem     | Ipsum    | 2010-12-25  | 1          | 4            | 1              | 4                 | 5               |

我已经阅读了很多关于MongoDB聚合管道的文章,但是还没有找到一个很好的解决方案。我知道这不是SQL,解决方案可能不会以这种精确的格式产生结果(尽管这将是惊人的)。我考虑过的一件事是将聚合和集合的结果结合起来,但这不是不可能的,就是我一直在用错误的条件进行搜索。$merge看起来很有希望,但是它会修改原始的集合,这是不好的。

我已经得到了以下内容,但结果不包括“行号”、特定工程师使用的杯子或工程师的ID和姓名。

代码语言:javascript
运行
复制
db.engineers.aggregate([
    {
        $group: {
            _id: '$BirthdateOn',
            TotalEngineers: {
                $count: {  }
            },
            TotalCupsOfCoffee: {
                $sum: '$CupsOfCoffee'
            },
            AvgHoursOfSleep: {
                $avg: '$HoursOfSleep'
            }
        }
    }
])

我的想法与组合是find所有的工程师,然后运行聚合,并“加入”它的工程师通过BirthdateOn

谢谢你的帮助!非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-22 19:32:23

你开了个好头。若要获取可以与$push运算符一起使用的输入数据,请执行以下操作。

是这样的:

代码语言:javascript
运行
复制
db.engineers.aggregate([
  {
    $group: {
      _id: "$BirthdateOn",
      TotalEngineers: { $count: {} },
      TotalCupsOfCoffee: { $sum: "$CupsOfCoffee" },
      AvgHoursOfSleep: { $avg: "$HoursOfSleep" },
      data: { $push: "$$ROOT" }
    }
  }
])

关于适当的输出尝试:

代码语言:javascript
运行
复制
db.engineers.aggregate([
  {
    $group: {
      _id: "$BirthdateOn",
      TotalEngineers: { $count: {} },
      TotalCupsOfCoffee: { $sum: "$CupsOfCoffee" },
      AvgHoursOfSleep: { $avg: "$HoursOfSleep" },
      data: { $push: "$$ROOT" }
    }
  },
  { $unwind: "$data" },
  { $replaceWith: { $mergeObjects: ["$$ROOT", "$data"] } }
])

通常情况下,运行$group和后来的$unwind是没有意义的,后者基本上恢复了以前的操作。

MongoDB版本5.0引入了$setWindowFields阶段,它非常类似于SQL函数:

我想应该是这个:

代码语言:javascript
运行
复制
db.engineers.aggregate([
  {
    $setWindowFields: {
      partitionBy: "$BirthdateOn",
      sortBy: { CupsOfCoffee: 1 },
      output: {
        TotalEngineers: { $count: {} },
        TotalCupsOfCoffee: { $sum: "$CupsOfCoffee" },
        AvgHoursOfSleep: { $avg: "$HoursOfSleep" },
        "Row Number": { $documentNumber: {} }
      }
    }
  }
])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73819560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档