REF:来自字段值为 max 的数组的 MongoDB 文档
从文档中的子数组中查找最高值和MongoDB通过文档数组中的最大值查找中的答案建议使用排序+限制(1),但这确实很慢。当然有一种方法可以使用 $max 运算符。
假设有人在聚合匹配中获得这样的文档:
{
_id: "notImportant",
array: [
{
name: "Peter",
age: 17
},
{
name: "Carl",
age: 21
},
{
name: "Ben",
age: 15
}
]
}
并且您想要找到年龄最高的(整个,而不仅仅是一个值)文档。 如何使用 $max 运算符做到这一点?
我试过了
unwind {"$array"}
project {"_id": 0, "name": "$array.name", "age": "$array.age"}
所以我明白了
{
_id: null,
name: "Peter",
age: 17
}
{
_id: null,
name: "Carl",
age: 21
}
{
_id: null,
name: "Ben",
age: 15
}
然后我尝试匹配年龄:
age: {$eq: {$max: "$age"}}
,但这没有给我任何结果。
换句话说,我需要获取的是属于数组中最老的人的姓名和所有其他字段。有成千上万的人,有很多属性,最重要的是它都在树莓派上运行。我需要对几十个这样的数组执行此操作。因此,排序总共需要大约 40 秒。所以我真的不想使用排序。
你可以用
$reduce
尝试一下这个聚合吗
db.t63.aggregate([
{$addFields : {array : {$reduce : {
input : "$array",
initialValue : {age : 0},
in : {$cond: [{$gte : ["$$this.age", "$$value.age"]},"$$this", "$$value"]}}
}}}
])
输出
{ "_id" : "notImportant", "array" : { "name" : "Carl", "age" : 21 } }
如果您想要所有具有最高价值的文档,您应该使用过滤器。 所以基本上,不要使用那些展开、项目等,只需使用下面的项目阶段
$project: {
age: {
$filter: {
input: "$array",
as: "item",
cond: { $eq: ["$$item.age", { $max: "$array.age" }] }
}
}
}
aggregation
db.collection.aggregate([
{ "$project": {
"max": {
"$arrayElemAt": [
"$array",
{
"$indexOfArray": [
"$array.age",
{ "$max": "$array.age" }
]
}
]
}
}}
])
{
$project: {
largeValue: {
$max: '$array.age',
},
},
}
对于您的第一个数据结构来说,这已经是足够的管道阶段了。不需要不必要的阶段(花费时间)。