mongo聚合计算每个文档的值最小

时间:2018-06-07 15:25:21

标签: mongodb aggregation

再次希望得到帮助..我想改变现有的汇总来自"只找到每种类型的最小值和最大值" to"找到最小值并计算每种类型的所有其他值的差异"。但我目前不知道如何将它们合并在一起。我可以单独查询并在nodejs中以某种方式进行计算,但我想知道如何在mongo聚合中进行此操作。

鉴于以下数据

    { departement : 'C_TG', type : 'FLAT_1', offer: 500, req: 495 }
    { departement : 'D_TG', type : 'FLAT_1', offer: 422, req: 420 }
    { departement : 'F_TG', type : 'FLAT_1', offer: 600, req: 480 }

    { departement : 'C_TG', type : 'FLAT_7', offer: 900, req: 889 }
    { departement : 'D_TG', type : 'FLAT_7', offer: 601, req: 500 }
    { departement : 'F_TG', type : 'FLAT_7', offer: 600, req: 590 }

    { departement : 'C_TG', type : 'FLAT_4', offer: 601, req: 599 }
    { departement : 'D_TG', type : 'FLAT_4', offer: 755, req: 735 }
    { departement : 'F_TG', type : 'FLAT_4', offer: 600, req: 590 }

我试图找到"最少"的差异。提供(对于每种类型(例如FLAT_1))所有文件(相同类型)。

因此,有必要

  • 表示每种类型(例如FLAT_1),
  • 找到此类型的最低报价(FLAT_1,在这种情况下为#34;报价:422"来自"部门:' D_TG'")
  • 把这个"至少_offer及其最小_offer_departement"记忆......
  • ...能够计算所有相同类型(FLAT_1)的差异,如

    (this.docs.req-least offer)/(最低报价/ 100)=百分比差异

  • 并打印包含least_offer + least_offer_departement +差异
  • 的所有文档

预期的结果最终会像

{ type : "FLAT_1", least_offer : 422, least_offer_departement : "D_TG", departement : "C_TG", req: 495, diff : 17.29 }
{ type : "FLAT_1", least_offer : 422, least_offer_departement : "D_TG", departement : "F_TG", req: 480, diff : 13.74 }
{ type : "FLAT_1", least_offer : 422, least_offer_departement : "D_TG", departement : "D_TG", req: 420 , diff : -0.47 }

{ type : "FLAT_7", least_offer : 600, least_offer_departement : "F_TG", departement : "C_TG", req: 889, diff : 48.16 }
{ type : "FLAT_7", least_offer : 600, least_offer_departement : "F_TG", departement : "F_TG", req: 590, diff : -1.66 }
{ type : "FLAT_7", least_offer : 600, least_offer_departement : "F_TG", departement : "D_TG", req: 500, diff : -16.66 }

{ type : "FLAT_4", least_offer : 600, least_offer_departement : "F_TG", departement : "C_TG", req: 599, diff : -0.16 }
{ type : "FLAT_4", least_offer : 600, least_offer_departement : "F_TG", departement : "F_TG", req: 590, diff : -1.66 }
{ type : "FLAT_4", least_offer : 600, least_offer_departement : "F_TG", departement : "D_TG", req: 735, diff : 22.5 }
最诚挚的问候,西蒙

1 个答案:

答案 0 :(得分:0)

哇哈哈,我自己做了..

结果与我最初想要的有点不同,但它给了我想要的信息

想要分享我的发现,也许别人可以从中获利。

我做了什么:

    db.prices.aggregate ([
        // only offers/request > 0, sometimes we get 0 values ..
        {
            $match : {
                offer : {
                    $gt : 0,
                },
                req : {
                    $gt : 0,
                },
            }
        },
        // sort them, to be able to find least offer
        {
            $sort: {
                'type': 1,
                'offer': 1,
            },
        },
        // then group them by type, and and get the least offer and its departement
        {
            $group: {
                _id: '$type',
                low_offer_departement: {
                    $first: '$departement'
                },
                low_offer: {
                    $first: '$offer'
                },
                // and push the current least offer and department to the document
                request : {
                    $push : {
                        departement : '$departement',
                        request: '$req',
                    }
                },
            }
        },
        // then we unwind "request subdocument" to create new documents, these are many ..
        {
            $unwind : '$request',
        },
        // now I can project and decide what I want to see in the result
        {
            $project : {
                _id : 0,
                request : 1,
                type: '$_id',
                low_offer_departement : '$low_offer_departement',
                low_offer : '$low_offer',
                // for each document, I want the difference between the "lowest offer"
                // and the "current" request
                diff : {
                    $divide : [
                        {
                            $subtract : [
                                '$request.request', '$low_offer'
                            ]
                        }, {
                            $divide : [
                                '$low_offer', 100
                            ]
                        }
                    ]
                }
            }
        },
        // and finally I am only interested in results between 5 and 20%
        {
            $match : {
                diff : {
                    $gt : 5,
                    $lt : 20
                }
            }
        },
        // this sort does not seem to make sense, but the final output is in a
        // table in a terminal, and I dont want too much change/movement in there
        {
            $sort: {
                type: 1
            }
        }
    ]);

所以在展开之前,我们得到以下结果:

{ "_id" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "request" : [ { "departement" : "F_TG", "request" : 590 }, { "departement" : "D_TG", "request" : 500 }, { "departement" : "C_TG", "request" : 889 } ] }
{ "_id" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "request" : [ { "departement" : "F_TG", "request" : 590 }, { "departement" : "C_TG", "request" : 599 }, { "departement" : "D_TG", "request" : 735 } ] }
{ "_id" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "request" : [ { "departement" : "D_TG", "request" : 420 }, { "departement" : "C_TG", "request" : 495 }, { "departement" : "F_TG", "request" : 480 } ] }

到目前为止很好,但我想要区别,所以我决定放松并继续格式化我的输出

放松和项目阶段后,我有

{ "request" : { "departement" : "F_TG", "request" : 590 }, "type" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -1.6666666666666667 }
{ "request" : { "departement" : "D_TG", "request" : 500 }, "type" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -16.666666666666668 }
{ "request" : { "departement" : "C_TG", "request" : 889 }, "type" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : 48.166666666666664 }
{ "request" : { "departement" : "F_TG", "request" : 590 }, "type" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -1.6666666666666667 }
{ "request" : { "departement" : "C_TG", "request" : 599 }, "type" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -0.16666666666666666 }
{ "request" : { "departement" : "D_TG", "request" : 735 }, "type" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : 22.5 }
{ "request" : { "departement" : "D_TG", "request" : 420 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : -0.47393364928909953 }
{ "request" : { "departement" : "C_TG", "request" : 495 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 17.298578199052134 }
{ "request" : { "departement" : "F_TG", "request" : 480 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 13.744075829383887 }

所以现在我可以过滤结果,只获得真正有趣的东西

最终导致2

{ "request" : { "departement" : "C_TG", "request" : 495 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 17.298578199052134 }
{ "request" : { "departement" : "F_TG", "request" : 480 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 13.744075829383887 }

我希望我在这里没有解释不可用的信息,如果有的话,请耐心等待我,我仍然是一个带有mongo和聚合的血腥混蛋;)

最诚挚的问候,西蒙