代码之家  ›  专栏  ›  技术社区  ›  Danny Buonocore DTM

从展开的数组中获取最大值

  •  2
  • Danny Buonocore DTM  · 技术社区  · 6 年前

    我有一个文档集合,我想在其中找到 data

    文件:

    [
        { 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 结果如何,但我很难搞清楚如何把所有的东西组合在一起。我拥有的文档数量不会太多,但是 数据 可以在低千,所以我不确定蒙戈将如何处理好做了一堆 $lookup 然后比较这些值。

    1 回复  |  直到 6 年前
        1
  •  1
  •   mickl    6 年前

    您可以尝试以下聚合:

    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"
                }
            }
        }
    ])
    

    $objectToArray $arrayToObject 在数组和对象之间转换。基本上,关键是对于每个需要生成的对象 nxn 3x3=9 在这种情况下)。您可以使用 $range 接线员。然后使用 $mod $divide $floor 你可以得到像这样的索引对 (0,0)...(2,2) $group 具有 $max 获取每对类型的最大值(如 a 具有 b 以此类推)。为了得到最终的形状,你还需要 $replaceRoot .

    输出:

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