MongoDB 聚合,获取值数组并获取其金额

问题描述 投票:0回答:1

这是我第一次在 StackOverflow 中提问,我希望我能解释一下我的目标。 我的文件看起来像这样:

    "_id" : ObjectId("5fd76b67a7e0fa652a297a9f"),
    "type" : "play",
    "session" : "5b0b5d57-c3ca-415f-8ef6-49bbd5805a23",
    "episode" : 1,
    "show" : 1,
    "user" : 1,
    "platform" : "spotify",
    "currentTime" : 0,
    "date" : ISODate("2020-12-14T13:40:51.906Z"),
    "__v" : 0
}

我想获取一个节目并按剧集对它们进行分组。我已经完成了我的聚合:

    const filter = { user, show, type: { $regex: /^(play|stop|close)$/ } }
    const requiredFields = { "episode": 1, "session": 1, "date": 1, "currentTime": 1 }
    // Get sessions grouped by episode
    const it0 = {
        _id: '$episode',
        session:
            {$addToSet:
                {_id: "$session",
                date:{$dateToString: { format: "%Y-%m-%d", date: "$date" }},
                averageOfSession: {$cond: [ { $gte: [ "$currentTime", 0.1 ] }, "$currentTime", null ] }
            },
            },
        count: { $sum: 1 }
    }
    // Filter unique sessions by session id and add them to a sessions field
    const reduceSessions = {$addFields:
            {sessions: {$reduce: {input: "$session",initialValue: [],in:
            {$concatArrays: ["$$value",{$cond: [{$in: ["$$this._id","$$value._id"]},[],["$$this"]]}]}
            }}}}

    const projection = { $project: { _id: 0, episode: "$_id", plays: {$size: '$sessions'}, dropoff: {$avg: "$sessions.averageOfSession"}, sessions: '$session.date', events: "$count" } }

        const arr = await Play.aggregate([
            { $match: filter }, {$project: requiredFields}, {$group: it0}, reduceSessions,
            projection,{ $sort : { _id : 1 } }
        ])

这就是我到目前为止的结果:

    {
        "episode": 5,
        "plays": 4,
        "dropoff": 3737.25,
        "sessions": [
            "2020-11-15",
            "2020-11-15",
            "2020-11-16",
            "2020-11-15"
        ],
        "events": 4
    }...

我想要的是“会话”数组成为一个对象,每个不同的日期都有一个键,其中包含计数,所以像这样:

 {
        "episode": 5,
        "plays": 4,
        "dropoff": 3737.25,
        "sessions": {
            "2020-11-15": 3,
            "2020-11-16": 1
        },
        "events": 4
    }...

希望这是有道理的,谢谢!

node.js mongodb mongoose nosql nosql-aggregation
1个回答
0
投票

您可以先将

sessions
映射为键值对。然后 $group 将它们相加。然后使用 $arrayToObject 转换为您想要的格式。

db.collection.aggregate([
  // your previous stages...
  {"$addFields": {
    "sessions": {
      "$map": {
        "input": "$sessions",
        "in": {
          "k": "$$this",
          "v": 1
        }
      }
    }
  }
},
{
  "$unwind": "$sessions"
},
{
  $group: {
    _id: {
      _id: "$_id",
      dropoff: "$dropoff",
      episode: "$episode",
      events: "$events",
      plays: "$plays",
      date: "$sessions.k"
    },
    count: {
      $sum: "$sessions.v"
    }
  }
},
{
  $group: {
    _id: {
      _id: "$_id._id",
      dropoff: "$_id.dropoff",
      episode: "$_id.episode",
      events: "$_id.events",
      plays: "$_id.plays"
    },
    sessions: {
      $push: {
        k: "$_id.date",
        v: "$count"
      }
    }
  }
},
{
  "$project": {
    _id: "$_id._id",
    dropoff: "$_id.dropoff",
    episode: "$_id.episode",
    events: "$_id.events",
    plays: "$_id.plays",
    sessions: {
      "$arrayToObject": "$sessions"
    }
  }
}
])

这个Mongo游乐场正在引用这个例子

© www.soinside.com 2019 - 2024. All rights reserved.