首页 > 解决方案 > 具有记录优先级的 Mongo 组聚合

问题描述

我正在尝试执行 MongoDB 3.6 聚合,但我想不出正确的方法。

问题如下。在执行了几个聚合步骤后,我最终得到了这样的结果集:

[
  { _id: { month: 1, type: 'estimate' }, value: 50 },
  { _id: { month: 2, type: 'estimate' }, value: 40 },
  { _id: { month: 3, type: 'estimate' }, value: 35 },
  { _id: { month: 3, type: 'exact' }, value: 33.532 },
  { _id: { month: 4, type: 'estimate' }, value: 10 },
  { _id: { month: 4, type: 'exact' }, value: 11.244 },
]

它包含按月份分组的值。每个月的价值可以是“估计的”或“准确的”。现在我想减少这个结果来实现这一点:

[
  { _id: { month: 1 }, value: 50 },
  { _id: { month: 2 }, value: 40 },
  { _id: { month: 3 }, value: 33.532 },
  { _id: { month: 4 }, value: 11.244 },
]

基本上,我想尽可能使用“精确”类型的值,并且只在“精确”未知的月份内回退到“估计”值。

任何帮助或提示将不胜感激。我想在数据库中而不是在服务器上执行聚合。

标签: mongodbaggregation-framework

解决方案


您可以简单地$sort bytype然后在下一个$group阶段使用$first ,如果存在,否则会给您。尝试:exactestimate

db.col.aggregate([
    {
        $sort: { "_id.type": -1 }
    },
    {
        $group:{
            _id: "$_id.month",
            value: { $first: "$value" }
        }
    },
    {
        $sort: { _id: 1 }
    }
])

印刷:

{ "_id" : 1, "value" : 50 }
{ "_id" : 2, "value" : 40 }
{ "_id" : 3, "value" : 33.532 }
{ "_id" : 4, "value" : 11.244 }

所以 sort bytype在这里被认为是优先级,因为我们知道词法exact上将是 before estimate。您还可以更明确地添加称为weight(使用$cond评估)运算符的额外字段,然后按该权重排序:

db.col.aggregate([
    {
        $addFields: { 
            weight: { $cond: [ { $eq: [ "$_id.type", "exact" ] }, 2, 1 ] } 
        }
    },
    {
        $sort: { "weight": -1 }
    },
    {
        $group:{
            _id: "$_id.month",
            value: { $first: "$value" }
        }
    },
    {
        $sort: { _id: 1 }
    }
])

推荐阅读