【问题标题】:Aggregate Count on Grouped Data分组数据的聚合计数
【发布时间】:2017-11-13 11:32:16
【问题描述】:

我有一个包含发票编号的文档和一个我指定发票类型的子文档

{  
    "inum" : "001",
    "date" : "28-May-2017",
    "value" : 10020, 
    "section" : { 
        "B2C" : false, 
        "B2B" : true
    } 
},
{  
    "inum" : "001",
    "date" : "22-May-2017",
    "value" : 3400, 
    "section" : { 
        "B2C" : false, 
        "B2B" : true
    } 
},
{  
    "inum" : "034",
    "date" : "22-May-2017",
    "value" : 80500, 
    "section" : { 
        "B2C" : true, 
        "B2B" : false
    } 
}

现在我根据发票编号对文档进行分组,并使用 mongoose 查询对其进行分组并获得预期结果。 所以它会给我一张发票,总金额为value,如下所示

{  
    "inum" : "001", 
    "value" : 13420, 
    "section" : { 
        "B2C" : false, 
        "B2B" : true
    } 
},
{  
    "inum" : "034",
    "date" : "22-May-2017",
    "value" : 80500, 
    "section" : { 
        "B2C" : true, 
        "B2B" : false
    } 
}

现在我想计算分组后不同部分类型的总发票数量,如上面的发票号码。有B2B & B2C 部分所以它应该给我

{"b2b":1,"b2c":1}

上面我可以通过为所有部分创建函数但我不想为个人创建函数我希望 mongodb 查询以获取所有部分的计数。

我做了如下

{
               $group: {
                   _id : {inum:"$inum"},  
                   b2b:  {$sum: {$cond: [{$eq:["$section.B2B", true]}, 1, 0]}},
         b2c:  {$sum: {$cond: [{$eq:["$section.B2C", true]}, 1, 0]}},
               }
           }, 
{$project: {_id:0}},

它让我计算未合并的发票号码 { "b2b":2, "b2c":1 }

但我想在分组数据后计数 { "b2b":1, "b2c":1}

【问题讨论】:

  • 如果我理解您的问题,您想要“合并”计数,对吗?如果是这样,是否存在相同发票的部分数据可能不同的情况。即假设第一个文档是{ "B2B": true, "B2C": false },而要“合并”的第二个文档是{ "B2B": false, "B2C": true },那么会发生什么?两者都是真的还是都是假的?或者这永远不会发生,两个要“合并”的文档应该具有相同的值?
  • 否...同一发票的部分数据不能不同...如果发票为B2Btrue,则仅适用于B2B,其他部分不会真的

标签: mongodb count aggregation-framework


【解决方案1】:

你想要“两个”$group 阶段在这里。一个在“inum”上分组时使用$first作为“部分”,另一个在null上使用实际$sum进行分组:

[
 { "$group": {
   "_id": "$inum",
   "section": { "$first": "$section" }
 }},
 { "$group": {
   "_id": null,
   "b2b": { "$sum": { "$cond": [ "$section.B2B", 1, 0 ] } },
   "b2c": { "$sum": { "$cond": [ "$section.B2C", 1, 0 ] } }
 }}
]

第一个只是根据您的请求“合并”,并且只保留找到的 $first "section" 数据。

后一种条件对所有文档进行累积,因为这是 null 作为分组键的评估结果。

这里的$cond 语法可以缩短,因为正在检查的三元表达式的第一个“if”条件实际上已经是一个“布尔”true/false 值。所以不需要额外的比较来强制转换为布尔值。

【讨论】:

  • 谢谢...它的工作,但有时它给了我一些意想不到的结果。让我看看这个……顺便谢谢
  • @SaurabhSharma 您可能“可能”遇到并非所有密钥都存在的问题。您可能会考虑在使用的特定键上包含一个带有$exists 的初始$match 阶段。或者,您可以在这种情况下使用$ifNull 扩展聚合逻辑。如果您仍有无法解决的特定问题,请Ask a new Question 有人会尝试解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 2014-09-14
  • 2014-02-27
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
相关资源
最近更新 更多