Mongodb 从展开的数组中获取最大值
我有一个文档集合,我想在其中找到Mongodb 从展开的数组中获取最大值,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有一个文档集合,我想在其中找到数据对象中每个可能字段对的每个比率的最大值。例如: 文件: [ { data: { a: 1, b: 5, c: 2 } }, { data: { a: 4, b: 1, c: 1 } }, { data: { a: 2, b: 4, c: 3 } } ] 期望输出: { a: { a: 1, b: 4, c: 4 }, b: { a: 5, b: 1, c: 2.5 }, c: { a: 2, b: 1, c
数据
对象中每个可能字段对的每个比率的最大值。例如:
文件:
[
{ data: { a: 1, b: 5, c: 2 } },
{ data: { a: 4, b: 1, c: 1 } },
{ data: { a: 2, b: 4, c: 3 } }
]
期望输出:
{
a: { a: 1, b: 4, c: 4 },
b: { a: 5, b: 1, c: 2.5 },
c: { a: 2, b: 1, c: 1 }
}
因此,输出a.b
是a:b比率1/5
、4/1
和2/4
中的最大值
所以我想我首先使用
$objectToArray
转换数据
,然后对结果使用$unwind
,但我很难弄清楚如何将所有内容组合在一起。我拥有的文档数量不会太多,但数据中的键数可能只有几千个,因此我不确定Mongo是否能够处理大量$lookup
,并比较类似的值。您可以尝试以下聚合:
db.col.aggregate([
{
$addFields: { data: { $objectToArray: "$data" } }
},
{
$project: {
pairs: {
$map: {
input: { $range: [ 0, { $multiply: [ { $size: "$data" }, { $size: "$data" } ] } ] },
as: "index",
in: {
$let: {
vars: {
leftIndex: { $floor: { $divide: [ "$$index", { $size: "$data" } ] } },
rightIndex: { $mod: [ "$$index", { $size: "$data" } ] }
},
in: {
l: { $arrayElemAt: [ "$data", "$$leftIndex" ] },
r: { $arrayElemAt: [ "$data", "$$rightIndex" ] }
}
}
}
}
}
}
},
{ $unwind: "$pairs" },
{
$group: {
_id: { l: "$pairs.l.k", r: "$pairs.r.k" },
value: { $max: { $divide: [ "$pairs.l.v", "$pairs.r.v" ] } }
}
},
{
$sort: {
"_id.l": 1, "_id.r": 1
}
},
{
$group: {
_id: "$_id.l",
values: { $push: { k: "$_id.r", v: "$value" } }
}
},
{
$addFields: { values: { $arrayToObject: "$values" } }
},
{
$project: {
root: [ { k: "$_id", v: "$values" } ]
}
},
{
$sort: { "root.k": 1 }
},
{
$replaceRoot: {
newRoot: {
$arrayToObject: "$root"
}
}
}
])
基本上,您需要在数组和对象之间进行转换。基本上,要点是,对于每个对象,您需要生成nxn
对(3x3=9
)。您可以使用运算符执行这样的迭代。然后使用and可以得到像(0,0)…(2,2)
这样的索引对。然后,您只需要使用获得每对类型的最大值(如a
withb
等等)。为了得到最终的形状,你还需要
产出:
{ "a" : { "a" : 1, "b" : 4, "c" : 4 } }
{ "b" : { "a" : 5, "b" : 1, "c" : 2.5 } }
{ "c" : { "a" : 2, "b" : 1, "c" : 1 } }