包含不同字段的最小值和最大值的聚合,包括输出

时间:2018-06-07 00:12:01

标签: mongodb aggregation-framework

我希望你能帮我解决一个问题,这是我的第一篇帖子,所以请耐心等待我,我会尽我所能。

在db.offers中提供以下数据

{ departement : 'C_TG', type : 'FLAT_1', offer: 500, req: 490 }
{ departement : 'C_TG', type : 'FLAT_1', offer: 600, req: 595 }
{ departement : 'F_TG', type : 'FLAT_1', offer: 600, req: 480 }
{ departement : 'C_TG', type : 'FLAT_7', offer: 900, req: 889 }
{ departement : 'C_TG', type : 'FLAT_1', offer: 460, req: 454 }
{ departement : 'F_TG', type : 'FLAT_4', offer: 600, req: 590 }
{ departement : 'C_TG', type : 'FLAT_4', offer: 601, req: 599 }
{ departement : 'D_TG', type : 'FLAT_1', offer: 422, req: 420 }
{ departement : 'D_TG', type : 'FLAT_7', offer: 600, req: 500 }

我想汇总数据以获得特定类型的最低报价和最高要求(req),包括负责的部门(!!)。 示例结果:

{ type: 'FLAT_1' offer: 422, offer_departement: 'D_TG', req: 595, req_departement: 'F_TG' }
{ type: 'FLAT_4' offer: 600, offer_departement: 'F_TG', req: 599, req_departement: 'C_TG' }
{ type: 'FLAT_7' offer: 600, offer_departement: 'D_TG', req: 889, req_departement: 'C_TG' }

到目前为止,我最好的结果是

[ { _id: { type: "FLAT_1", offer_departement: "D_TG" }, req: 595 } ]

但是这里有关于"请求信息的所有信息"失踪了,所以它真的没有意义.. 我已经分组和排序,也进行了多个小组阶段等等,但要么我得到一个完整的项目列表,而不是" $ min"在帐户中,或者我无法将部门纳入offer_departement ......

在我决定寻求帮助之前,我最近的方法是

db.prices.aggregate ([
        {
            $match : {
                offer : {
                    $ne : "0",
                },
                request : {
                    $ne : "0",
                },
            }
        },
        {
            $group : {
                _id : {
                    type : '$type',
                    dep : '$departement',
                },
                offer : {
                    $min : '$offer',
                },
                request : {
                    $max : '$req',
                }
            }
        },
    ]);

但当然结果远非我的目标,我尝试了几十个答案,也来自SO,但我没有得到它。

我真的很感激一些帮助!

最诚挚的问候,西蒙

1 个答案:

答案 0 :(得分:0)

而不是$min$max您需要在此处执行的操作首先是$sort输入,然后使用$first$last累加器分组边界:

db.prices.aggregate([
  { "$match": { "offer": { "$gt": 0 } , "req": { "$gt": 0 } } },
  { "$sort": { "type": 1, "offer": 1, "req": 1 } },
  { "$group": {
    "_id": "$type",
    "offer_departement": { "$first": "$departement" },
    "offer": { "$first": "$offer" },
    "req_departement": { "$last": "$departement" },
    "req": { "$last": "$req" }
  }},
  { "$sort": { "req": 1 } }
])

返回:

{
        "_id" : "FLAT_1",
        "offer_departement" : "D_TG",
        "offer" : 422,
        "req_departement" : "C_TG",
        "req" : 595
}
{
        "_id" : "FLAT_4",
        "offer_departement" : "F_TG",
        "offer" : 600,
        "req_departement" : "C_TG",
        "req" : 599
}
{
        "_id" : "FLAT_7",
        "offer_departement" : "D_TG",
        "offer" : 600,
        "req_departement" : "C_TG",
        "req" : 889
}

同样更好一点“明智的索引使用”是使用$gt而不是$ne,因为“不等式”无法有效地使用“范围”(即使是开放)的索引。因此,只要这些不是负数,那么这将是一个更好的方法。

另请注意,$group没有明确的输出顺序,因此如果您需要特定订单,请在$sort之后应用$group