如何获取MongoDB中最近n个月的记录(只考虑每月最后一个条目)



我是MongoDb的新手。我需要帮助获取最近n个月的记录,每个月可能有多个条目,但查询只需要返回每月的最后一个条目。

例如,假设n为3, userId为userId1(这意味着返回userId1的最近3个月记录)。

集合中的样例输入:

[
{
"_id": objectId("aaaaaa"),
"userId": "userId1",
"processedAt": "2021-06-01T12:16:49.349Z"
},
{
"_id": objectId("bbbbb"),
"userId": "userId1",
"processedAt": "2021-10-11T12:16:49.349Z"
},
{
"_id": objectId("ccccc"),
"userId": "userId1",
"processedAt": "2021-10-25T12:16:49.349Z"
},
{
"_id": objectId("eeeee"),
"userId": "userId1",
"processedAt": "2021-09-12T12:16:49.349Z"
},
{
"_id": objectId("fffff"),
"userId": "userId1",
"processedAt": "2021-09-28T12:16:49.349Z"
},
{
"_id": objectId("ggggg"),
"userId": "userId1",
"processedAt": "2021-09-23T12:16:49.349Z"
},
{
"_id": objectId("hhhhh"),
"userId": "userId1",
"processedAt": "2021-07-23T12:16:49.349Z"
},
{
"_id": objectId("iiiii"),
"userId": "userId2",
"processedAt": "2021-09-29T12:16:49.349Z"
},
{
"_id": objectId("jjjjj"),
"userId": "userId1",
"processedAt": "2022-01-29T12:16:49.349Z"
},
{
"_id": objectId("kkkkk"),
"userId": "userId1",
"processedAt": "2022-02-29T12:16:49.349Z"
}, 
]

预期结果:应该按userId返回,限制n个月(只获取该月最后保存的条目),processsedat的月份升序:

[{
"_id": objectId("ccccc"),
"userId": "userId1",
"processedAt": "2021-10-25T12:16:49.349Z"
},
{
"_id": objectId("jjjjj"),
"userId": "userId1",
"processedAt": "2022-01-29T12:16:49.349Z"
},
{
"_id": objectId("kkkkk"),
"userId": "userId1",
"processedAt": "2022-02-29T12:16:49.349Z"
}
]

我已经尝试了下面的查询,但是它返回所有的记录。我想查询需要只考虑每月最后一个条目。我一直在使用mongojs驱动程序v4.1.2

db.collection(collection_name)
.find({ userId: userId }, { projection: { _id: 0 } })
.sort({ processedAt: -1 })
.limit(n)
.toArray()

从MongoDB 5.0开始,

你可以使用$setWindowFields来聚合一个"排名"。对于"分区"/"group"(即在您的例子中的月份),并且只选择排名最高的文档。

排名可以定义为processedAt: -1,因为您只想保留排名最高的月份的最新记录。

{
"$setWindowFields": {
"partitionBy": {
"$dateToString": {
"date": "$processedAt",
"format": "%Y-%m"
}
},
"sortBy": {
"processedAt": -1
},
"output": {
"rank": {
$rank: {}
}
}
}
}

这是Mongo游乐场供您参考。

对于MongoDB 3.6+,

由于样本数据集使用ISODate格式,因此可以按最左边的7个字符(即yyyy-MM)对字段进行排序和分组。在month组中只保留第一个文档应该可以达到目的。

{
$sort: {
processedAt: -1
}
},
{
"$addFields": {
"month": {
"$substrCP": [
"$processedAt",
0,
7
]
}
}
},
{
$group: {
_id: "$month",
last: {
$first: "$$ROOT"
}
}
}

这里是Mongo游乐场。

相关内容

  • 没有找到相关文章

最新更新