Mongodb 带计数的不同查询

Mongodb Distinct Query with Count

我在 mongodb

中有如下架构
let reactions = [

  {
      messageId: 1,
      reactions: [
          {
              "userid": "7212898122",
              "reactionId": 2,
              "date": "2022-05-12T18:55:49.943Z"
          },
          {
              "userid": "8171763225",
              "reactionId": 2,
              "date": "2022-05-12T19:27:34.324Z"
          },
          {
              "userid": "8782323232",
              "reactionId": 3,
              "date": "2022-05-12T18:55:49.943Z"
          }
      ]

  },

  {
      messageId: 2,
      reactions: [
          {
              "userid": "7212898122",
              "reactionId": 1,
              "date": "2022-05-12T18:55:49.943Z"
          },
          {
              "userid": "8171763225",
              "reactionId": 2,
              "date": "2022-05-12T19:27:34.324Z"
          },
          {
              "userid": "8782323232",
              "reactionId": 1,
              "date": "2022-05-12T18:55:49.943Z"
          }
      ]

  }

]

我想要这样的结果

    let result = [
    {
        messageId:1,
        count:{
            2:2,
            3:1
        }
    },

    {
        messageId:1,
        count:{
            1:2,
            2:1
        }
    }
]

表示两个用户对 reactionId 2 做出了反应,一个用户对 reactionId 1 做出了反应,与所有 messageId 相同

我试过组,但没有得到我想要的结果。请回答。

===================================

您可以这样做:

  1. $unwind 分离反应
  2. $group 同时通过 messageId 和 reactionId,得到你想要的计数
  3. $group 通过 messageId 到 'revert' $unwind 并在数组中使用 kv 以启用转换为对象。
  4. $project 格式化为对象
db.collection.aggregate([
  {
    $unwind: "$reactions"
  },
  {
    $group: {
      _id: {
        messageId: "$messageId",
        reactionId: "$reactions.reactionId"
      },
      count: {$sum: 1}
    }
  },
  {
    $group: {
      _id: "$_id.messageId",
      count: {
        $push: {k: {$toString: "$_id.reactionId"}, v: "$count"}}
    }
  },
  {
    $project: {
      messageId: "$_id",
      _id: 0,
      count: {$arrayToObject: "$count" }
    }
  }
])

但在 mongodb 上,键应该是字符串。

playground example