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
with
b
等等)。为了得到最终的形状,你还需要

产出:

{ "a" : { "a" : 1, "b" : 4, "c" : 4 } }
{ "b" : { "a" : 5, "b" : 1, "c" : 2.5 } }
{ "c" : { "a" : 2, "b" : 1, "c" : 1 } }