MongoDb 将 $group '_id' 空值聚合为不同的

Posted

技术标签:

【中文标题】MongoDb 将 $group \'_id\' 空值聚合为不同的【英文标题】:MongoDb Aggregate $group '_id' null values as distinctMongoDb 将 $group '_id' 空值聚合为不同的 【发布时间】:2016-04-10 17:22:42 【问题描述】:

我有以下数据结构:


    "_superBill": 
        "$oid": "568b250ba082dfc752b20021"
    ,
    "paymentProviderTxID": "aaaa",
    "transactionRaw": "abcdef",
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-26T13:04:05.544Z"
      
,

    "_superBill": 
        "$oid": "568b250ba082dfc752b20021"
    ,
    "paymentProviderTxID": "bbbb",
    "transactionRaw": "abcdef",
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-26T13:04:05.544Z"
      
,

    "_superBill": null,
    "paymentProviderTxID": "cccc",
    "transactionRaw": "abcdef",
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-27T13:04:05.544Z"
    
,

    "_superBill": null,
    "paymentProviderTxID": "dddd",
    "transactionRaw": "abcdef",
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-28T13:04:05.544Z"
    

我有一个按引用的 _superBill 字段分组的聚合函数。在我遇到 _superBill 具有 null 值的条目并将它们全部归为一个之前,它的效果很好。

有没有一种方法可以只对具有有效 _superBill 的条目进行分组,同时仍包含具有“null”的值,以便我可以在一个查询中执行此操作并按 visitDate 对它们进行排序?

聚合函数:

Transaction.aggregate([
     $match:  paymentDate:  $gte: period.periodStart, $lt: period.periodEnd  ,
    
        $group: 
            _id: "$_superBill",
            visits:  $sum: 1              
        
    ,
    
        $project: 
            _id: '$_id',
            superBill: '$_id',
            visits: '$visits',          
            visitDate: '$visitDate',
            commissionRate: '$commissionRate'

        
    
], function(err,results) 
    // Process results
);

结果集如下所示。请注意,前 2 个已分组,因为它们具有相同的 _superBill _id,而其他两个未分组。


    "_superBill": 
        "$oid": "568b250ba082dfc752b20021"
    ,
    "visits": 1,
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-26T13:04:05.544Z"
      
,

    "_superBill": null,
    "visits": 1,
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-27T13:04:05.544Z"
    
,

    "_superBill": null,
    "visits": 1,
    "commissionRate": 0.2,
    "visitDate": 
        "$date": "2016-12-28T13:04:05.544Z"
    

感谢您的关注并感谢任何帮助。

【问题讨论】:

您可能希望在您的组管道中使用 $ifNull 运算符,并在同一 $group 管道中使用 $first 运算符来创建其他字段以进一步投射到管道中。跨度> 谢谢@chridam。我查看了 $ifNull 运算符,看起来我可以向空字段添加默认值。抱歉,如果我没有正确理解这一点,但这只会为其分组分配相同的值,除非 $ifNull 可以递增或随机化。我也不确定 $first 运算符如何与 $ifNull 结合使用。 【参考方案1】:

如果_superBill 等于null,您可以使用_id$group 您的文档。为此,您可以使用 $ifNull 运算符。

Transaction.aggregate(
    [ 
         "$group":  
             "_id":  "$ifNull": [ "$_superBill", "$_id" ] ,  
             "visits":  "$sum": 1 , 
             "visitDate":  "$first": "$visitDate" ,
             "commissionRate":  "$first": "$commissionRate" , 
             "_superBill":  "$first": "$_superBill"  
        
    ],  function(err,results) 
           // Process results
        
)

当然你也可以使用$cond操作符。

"_id":  
    "$cond": [ 
         "$eq": [ "$_superBill", null ] , 
        "$_id", 
        "$_superBill" 
    ] 

【讨论】:

这完全成功了。我不知道您可以退回到 $ifNull 运算符中的另一个字段!非常感谢您的帮助。

以上是关于MongoDb 将 $group '_id' 空值聚合为不同的的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB group count 慢(qbit)

MongoDB $lookup 和 $group 返回空数组

$group mongodb 后获取常用元素

mongodb 聚合操作

MongoDB 嵌入式对象没有 ID(空值)

MongoDB 允许磁盘使用不工作..