我有一些数据如下:
{'Type':'A',
'Attributes':[
{'Date':'2021-10-02', 'Value':5},
{'Date':'2021-09-30', 'Value':1},
{'Date':'2021-09-25', 'Value':13}
]
},
{'Type':'B',
'Attributes':[
{'Date':'2021-10-01', 'Value':36},
{'Date':'2021-09-15', 'Value':14},
{'Date':'2021-09-10', 'Value':18}
]
}
我想查询每个文档的最新日期的文档。根据以上数据,期望的结果将是:
{'Type':'A', 'Date':'2021-10-02', 'Value':5}
{'Type':'B', 'Date':'2021-10-01', 'Value':36}
我设法找到一些查询来查找所有子文档中的全局最大值。但我没有找到每个文档的最大值。
非常感谢您的帮助
从 MongoDB v5.0+ 开始,您可以使用
$setWindowFields
计算 $rank
文档的 $unwind
并选择 rank: 1
条目。
db.collection.aggregate([
{
"$unwind": "$Attributes"
},
{
"$setWindowFields": {
"partitionBy": "$_id",
"sortBy": {
"Attributes.Date": -1
},
"output": {
"rank": {
"$rank": {}
}
}
}
},
{
"$match": {
"rank": 1
}
},
{
$project: {
Type: 1,
Date: "$Attributes.Date",
Value: "$Attributes.Value"
}
}
])
将日期存储为字符串通常被认为是不好的做法。建议您将日期字段更改为日期类型。幸运的是,对于您的情况,您使用的是 ISO 日期格式,因此可以节省一些精力。
您可以在聚合管道中执行此操作:
$max
找出最大日期$filter
过滤 Attributes
数组以仅包含最新元素$unwind
数组$project
达到您的预期输出db.collection.aggregate([
{
"$addFields": {
"maxDate": {
$max: "$Attributes.Date"
}
}
},
{
"$addFields": {
"Attributes": {
"$filter": {
"input": "$Attributes",
"as": "a",
"cond": {
$eq: [
"$$a.Date",
"$maxDate"
]
}
}
}
}
},
{
$unwind: {
path: "$Attributes",
preserveNullAndEmptyArrays: true
}
},
{
$project: {
Type: 1,
Date: "$Attributes.Date",
Value: "$Attributes.Value"
}
}
])
这里是Mongo游乐场供您参考。
这仅保留属性中的 1 名成员,即具有最大日期的成员。 如果您想保留多个成员,请使用 @ray 解决方案,该解决方案保留具有最大日期的所有成员。
*mongoplayground 可能会丢失文档中字段的顺序, 如果你看到错误的结果,请在你的驱动程序上测试它,这是 mongoplayground 工具的错误
查询1(本地方式)
aggregate([
{
"$project": {
"maxDateValue": {
"$max": {
"$map": {
"input": "$Attributes",
"in": { "Date": "$$this.Date", "Value": "$$this.Value" },
}
}
},
"Type": 1
}
},
{
"$project": {
"Date": "$maxDateValue.Date",
"Value": "$maxDateValue.Value"
}
}
])
查询2(展开方式)
aggregate([
{
"$unwind": { "path": "$Attributes" }
},
{
"$group": {
"_id": "$Type",
"maxDate": {
"$max": {
"Date": "$Attributes.Date",
"Value": "$Attributes.Value"
}
}
}
},
{
"$project": {
"_id": 0,
"Type": "$_id",
"Date": "$maxDate.Date",
"Value": "$maxDate.Value"
}
}
])