简体   繁体   中英

Mongodb aggregation distinct, average and sum with group by between two collection

I have user collection having data like this

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

and On the other hand userlogs has data like this

{
    "_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
}

What I am trying to do is equivalent to this sql query

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.

I can do normal group by and sum together.But How to do avg distinct and count distinct with this? I am using mongodb version 3.2

I don't think this require $group stage, you can use $setUnion and $size , $avg operators,

  • $lookup with userlogs collection
  • $project to show required fields, and filter userlogs as per your condition
  • $project to get statistics from userlogs
    • get total logs count using $size
    • get total duration sum using $sum
    • get average of unique label using $setUnion and $avg
    • get count of unique bookId using $serUnion and $size
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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM