【问题标题】:mongo aggregation calculate on each document with least valuemongo聚合计算每个文档的最小值
【发布时间】:2018-06-10 22:12:33
【问题描述】:

再次希望得到帮助.. 我想将现有聚合从“仅查找每种类型的最小值和最大值”更改为“查找最小值并计算每种类型的所有其他值的差异”。但我目前不知道如何将它们合并在一起。我可以分别查询两者并在 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,在本例中为来自“部门:'D_TG'”的“报价:422”)
  • 把这个“least_offer 和它的 minimum_offer_departement”放到内存中...
  • ...能够计算所有相同类型(FLAT_1)集合的差异

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

  • 并打印所有文档,包括 minimum_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 }

最好的问候,西蒙

【问题讨论】:

  • 真的不清楚你在问什么。现有的聚合是按类型“分组”的,结果现在与原始文档没有任何关系。甚至百分比都不清楚。也许您应该尝试通过说明从“原始状态”到“最终所需状态”的数据组织中需要发生什么来进行逻辑解释。如果您不了解所有聚合管道术语和用法,那么您只是通过尝试解释如何使用它们来混淆问题。只需解释需要对数据进行哪些处理即可。
  • 早上好,请道歉,让我试着把它说清楚。我想要实现的基本上是,对于每种类型(例如类型:“FLAT_1”),最低报价(例如报价:422)被用作计算与 all 更高的差异的基础请求(例如 req: 590)。结果应包括两者之间的百分比差异和部门。所以结果,“offer”的部门总是一样的,因为它是offer最少的部门。我希望这有助于使它更清楚?最好的问候
  • 不,它并没有使它更清晰。您被要求"edit your question" 并“通过示例”展示您希望如何根据源数据获得结果。问题中已经出现的单词并不清楚。添加更多的单词并不能使它更清楚。花点时间让问题尽可能清晰。另见stackoverflow.com/help/how-to-ask

标签: mongodb aggregation


【解决方案1】:

哇哈哈,我自己做的..

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

想分享我的发现,也许其他人可以从中受益。

我做了什么:

    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 和聚合的该死的混蛋;)

最好的问候,西蒙

【讨论】:

  • 可以接受我自己的答案吗?嗯,我希望如此:p
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
相关资源
最近更新 更多