【问题标题】:Mongodb aggregation distinct, average and sum with group by between two collectionMongodb聚合distinct,average和sum与两个集合之间的group by
【发布时间】:2021-01-03 14:57:54
【问题描述】:

我的 用户 集合包含这样的数据

{
    "_id" : ObjectId("5da594c15324fec81d000027"),
    "password" : "******",
    "activation" : "Active",
    "userType" : "Author",
    "email" : "something@gmail.com",
    "name" : "Something",
    "profilePicture" : "profile_pictures/5da594c15324fec81d0000271607094354423image.png",
    "__v" : 0
}

另一方面 userlogs 有这样的数据

{
    "_id" : ObjectId("5fcb7bb4485c34a41900002b"),
    "duration" : 2.54,
    "page" : 1,
    "activityDetails" : "Viewed Page for seconds",
    "contentType" : "article",
    "activityType" : "articlePageStayTime",
    "label" : 3,
    "bookId" : ObjectId("5f93e2cc74153f8c1800003f"),
    "ipAddress" : "::1",
    "creator" : ObjectId("5da594c15324fec81d000027"),
    "created" : ISODate("2020-12-05T12:23:16.867Z"),
    "__v" : 0
}

我正在尝试做的相当于这个 sql 查询

SELECT name,count(page),sum(duration),avg(DISTINCT(label)),COUNT(DISTINCT(bookId)) FROM users JOIN userlogs ON users._id=userlogs.creator where userlogs.activityType<>"articleListeningTime" group by users._id.

我可以一起做正常的group bysum。但是如何做avg distinctcount distinct 呢?我正在使用 mongodb 3.2 版

【问题讨论】:

  • 您是否将密码存储为明文?你不应该这样做,而是存储一个哈希值。
  • 感谢朋友的提问!我将其存储为哈希值。粘贴到这里后就用星号替换了。

标签: node.js mongodb nosql aggregation-framework


【解决方案1】:

我认为这不需要$group 阶段,您可以使用$setUnion$size$avg 运算符,

  • $lookupuserlogs 收藏
  • $project 显示必填字段,并根据您的条件过滤 userlogs
  • $projectuserlogs 获取统计信息
    • 使用$size获取总日志计数
    • 使用$sum获取总持续时间总和
    • 使用$setUnion$avg 获取唯一标签的平均值
    • 使用$serUnion$size 获取唯一bookId 的计数
db.users.aggregate([
  {
    $lookup: {
      from: "userlogs",
      localField: "_id",
      foreignField: "creator",
      as: "userlogs"
    }
  },
  {
    $project: {
      name: 1,
      userlogs: {
        $filter: {
          input: "$userlogs",
          as: "u",
          cond: { $ne: ["$$u.activityType", "articleListeningTime"] }
        }
      }
    }
  },
  {
    $project: {
      name: 1,
      totalCount: { $size: "$userlogs" },
      durationSum: { $sum: "$userlogs.duration" },
      labelAvg: { $avg: { $setUnion: "$userlogs.label" } },
      bookIdCount: { $size: { $setUnion: "$userlogs.bookId" } }
    }
  }
])

Playground

【讨论】:

  • 谢谢!它仅在过滤器中添加“as”后才起作用。顺便说一句,您的意思是“使用 $setUnion 和 $size 计算唯一 bookId 的数量”吗?
  • 好吧,“as”在 $filter 的最新版本中是可选的,最后一点是的,我已经纠正了两个错误。
  • 谢谢!没想到没有 group by 是不可能的!
猜你喜欢
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-04-29
  • 2014-11-22
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多