【问题标题】:Mongodb Aggregation group by on more than one fieldMongodb 聚合根据多个字段分组
【发布时间】:2018-04-05 15:16:39
【问题描述】:

我正在对一个集合应用聚合,我想按多个字段进行分组。管道中的所有计算都是相同的。我想查看按不同字段分组的结果。

我正在使用的字段的可能值:

ageCategory -> 10, 20, 30 40
sex -> Male, Female
type -> A,B,C,D,E
stage -> I, II, III, IV

这就是我现在的做法:

mongoose.connection.db.collection("collection").aggregate([
            { $match: //match conditions },
            { $project: { 
                   ageCategory: 1,
                   sex: 1,
                   type: 1,
                   stage: 1,
                   //other fileds
                } 
            },
            { $match: //match conditions } ,
            { $project: { 
                   ageCategory: 1,
                   sex: 1,
                   type: 1,
                   stage: 1,
                   //other fileds
                } 
            },
            {
                $group: {
                    _id: "result",
                    age10: { $sum: { $cond:[//condition for ageCategory 10,1,0]  } },
                    age20: { $sum: { //condition for ageCategory 10  } },
                    //other age categories
                    male: { $sum: { //condition for male  } },
                    female: { $sum: { //condition for female  } },                        
                    typeA: { $sum: { //condition for type A } },
                    typeB: { $sum: { //condition for type B  } },
                    //other conditions
                }
           }
        ]).toArray(function (err, result) {
            //final computations
        });

预期的数据和结果的简化表示:(在 match 和 project 语句中发生了一些计算,为简单起见将其忽略)

[{
    ageCategory: "10",
    sex: "Male",
    type: "A",
    stage: "I",
    sub:[
        {}
    ],
    //other sub documents that are used in the pipeline
},
{
    ageCategory: "20",
    sex: "Male",
    type: "B",
    stage: "I",
    sub:[
        {}
    ],
    //other sub documents that are used in the pipeline
}]

预期结果:

{
    age10:1, //count of sub with ageCategory as 10
    age20:1,
    //other count by age. It is okay to ignore the ones with zero count.
    male: 2,
    typeA: 1,
    typeB: 1,
    stageI: 2
}

我正在检查 group by 中的所有条件。我不确定这是否是最好的方法。一种选择是多次运行此聚合,并将 group by 应用于单个字段,但这会导致性能问题并且还会重复相同的查询。

由于性能原因,我无法使用 mapReduce。

这是最好的方法吗?或任何替代方法?

【问题讨论】:

  • 那么您的确切问题是什么?
  • 更新了我的问题。谢谢
  • 您能否提供一个输入数据和预期输出的简单示例?
  • @cbartosiak 为问题添加了示例数据。
  • 你能解释一下为什么stageI等于"I"吗?

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

根据提供的预期结果,可以肯定地说您想要获得总计。在这种情况下,您应该按 null 而不是 "result" 对文档进行分组,因为我们不知道这对 Mongo 未来可能意味着什么。

我认为您的问题的问题在于您使用“分组依据”术语,但实际上您的意思是计算字段包含一些累加器表达式的值。

嗯,你这样做的方式对我来说似乎没问题(除了 null/"result" 事情)。

【讨论】:

  • 您对 groupby 的看法完全正确。但是在 $group 中使用带有条件的 $project 与在 $group 中使用相同条件的优势是什么?使用我现有的代码,我得到了预期的结果。
  • 我已经编辑了我的答案以专注于关键点并且不误导人们。如果您不必在$group 之前不要使用$project,因为它可能比您使用的内联要慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-19
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多