【问题标题】:Mongo groupby date inside arrayMongodb按数组内的数据分组
【发布时间】:2023-04-06 22:26:01
【问题描述】:

我的数据库中有集合,

[
    {
        "groupName" : "testName",
        "participants" : [
            {
                "participantEmail" : "test@test.com",
                "lastClearedDate" : 12223213123
            },
             {
                "participantEmail" : "test2@test.com",
                "lastClearedDate" : 1234343243423
            }
        ],
        "messages" : [
            {
                "message":"sdasdasdasdasdasd",
                "time":22312312312,
                "sender":"test@test.com"
            },
            {
                "message":"gfdfvd dssdfdsfs",
                "time":2231231237789,
                "sender":"test@test.com"
            }
        ]
    }
]

这是一个组的集合,其中包含该组中的所有参与者和消息。 消息中的时间字段是时间戳。

我想获取在给定日期之后发布并按日期分组的组内的所有消息。 我写了以下代码,

      ChatGroup.aggregate([
        { $match: { group_name: groupName } },
        { $unwind: "$messages" },
        { $match: { "messages.time": { $gte: messagesFrom } } },
        {
          $project: {
            _id: 0,
            y: {
              $year: {
                $add: [new Date(0), { $multiply: [1000, "$messages.time"] }]
              }
            },
            m: {
              $month: {
                $add: [new Date(0), { $multiply: [1000, "$messages.time"] }]
              }
            },
            d: {
              $dayOfMonth: {
                $add: [new Date(0), { $multiply: [1000, "$messages.time"] }]
              }
            }
          }
        },
        {
          $group: {
            _id: {
              year: "$y",
              month: "$m",
              day: "$d"
            },
            messages: { $push: "$messages" },
            count: { $sum: 1 }
          }
        }
      ]).then(
        group => {
          console.log("length of messages", group);
          resolve(group);
        },
        err => {
          console.log(err);
        }
      );
    });

我得到以下输出,

[
    {
        "_id": {
            "year": 50694,
            "month": 9,
            "day": 5
        },
        "messages": [],
        "count": 3
    },
    {
        "_id": {
            "year": 50694,
            "month": 8,
            "day": 27
        },
        "messages": [],
        "count": 1
    },
    {
        "_id": {
            "year": 50694,
            "month": 8,
            "day": 26
        },
        "messages": [],
        "count": 10
    }
]

我没有收到消息,但计数是正确的。 结果中显示的时间也不正确,例如年、日期和月份。 Mongo 版本是 3.2。

我参考了来自 mongodb 的 groupby 和推送文档以及关于 mongo group by 的其他 stackoverflow 问题。

我做错了什么?

【问题讨论】:

  • 删除$multiply 1000

标签: mongodb mongoose aggregation-framework


【解决方案1】:

您的时间戳已经以秒为单位。因此,您无需乘以 1000 将它们转换为毫秒。

所以你的最终查询应该是这样的

ChatGroup.aggregate([
  { "$match": {
    "group_name": groupName,
    "messages.time": { "$gte": messagesFrom }
  }},
  { "$unwind": "$messages" },
  { "$match": { "messages.time": { "$gte": messagesFrom }}},
  { "$group": {
    "_id": {
      "year": { "$year": { "$add": [new Date(0), "$messages.time"] }},
      "month": { "$month": { "$add": [new Date(0), "$messages.time"] }},
      "day": { "$dayOfMonth": { "$add": [new Date(0), "$messages.time"] }}
    },
    "messages": { "$push": "$messages" },
    "count": { "$sum": 1 }
  }}
])

【讨论】:

  • 当我执行上述查询时,我得到了正确的时间,但所有消息都被分组在同一个桶中,这是不正确的。而通过乘法,我得到了正确的结果,但时间不正确。
  • 不,这是正确的。看看mongoplayground.net/p/Tnhcd31XWU5
  • 版本是 4.0.1,我在问题中提到我使用的是 3.2。在 mongo 4 中,我读到使用类似 $toDate 的方式直接支持按时间分组
  • 无关紧要,所有聚合器运算符在 3.2 版中也可用,为了获得更好的性能,您应该更新您的版本
  • 我复制粘贴了这个查询,它工作了,以前我只是选择了你的 _id 部分,没有添加 gte 过滤器,因此计数不正确感谢和抱歉不正确的响应
【解决方案2】:

$project中添加messages

{
          $project: {
            _id: 0,
            messages : 1,
           .........
        },
}

【讨论】:

  • 这可行,但年、月和日期字段不正确..您有什么建议吗?
猜你喜欢
  • 2014-02-25
  • 2017-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2019-02-11
  • 2021-07-18
相关资源
最近更新 更多