2017-05-04 181 views
1

鉴于以下文档。用于计算多个计算值的Mongo聚合查询

{ 
    _id: 1, 
    ExpirationDate: ISODate("2017-05-02T09:29:46.006+0000") 
} 
{ 
    _id: 2, 
    ExpirationDate: ISODate("2017-05-12T09:29:46.006+0000") 
} 
{ 
    _id: 3, 
    ExpirationDate: ISODate("2017-05-23T09:29:46.006+0000") 
} 

如何使用聚合pipleline来计算以下输出?

{ 
    "NumberOfSubscriptionExpiringToday": 12, 
    "NumberOfSubscriptionExpiringWithInAWeek": 4 
} 

我期待着用一个查询而不是两个来完成这个任务。以下是我迄今为止...

{ $match: { "ExpirationDate": {$gte: ISODate("2017-05-02T00:00:00.000+0000"), $lte: ISODate("2017-05-03T00:00:00.000+0000")}}}, 
{ $project: {_id:1} }, 
{ $count: "ExpiringToday" } 
]); 

{ $match: { "ExpirationDate": {$gte: ISODate("2017-05-02T00:00:00.000+0000"), $lte: ISODate("2017-05-08T00:00:00.000+0000")}}}, 
{ $project: {_id:1} }, 
{ $count: "ExpiringInSevenDays" } 
]); 
+0

你为什么选择只有一天时间范围?什么是仅选择_id字段的目的?并且您没有ExpiringToday字段,尤其是在选择了_id –

+0

之后,我可以从七天的范围开始,然后通过另一个$匹配阶段来获得一天范围并投影它。我需要使用$ addToFields来计算一天七天的范围吗? – GBackMania

+0

@SergeyBerezovskiy更新了我的问题。我如何将两个查询合并为一个? – GBackMania

回答

1

你可以做到这一点单查询聚集与$cond运营商,以检查是否每个文档到期日期落入[today, tomorrow)范围,或在[tomorrow, weekAfterToday)范围:

var today = ISODate("2017-05-04T00:00:00.000"); 
var tomorrow = ISODate("2017-05-05T00:00:00.000"); 
var weekAfterToday = ISODate("2017-05-11T00:00:00.000"); 

db.collection.aggregate([ 
    { $match: { "ExpirationDate": { $gte: today, $lt: weekAfterToday }}}, 
    { 
     $project: { 
     ExpiringToday: { 
      $cond: { 
       if: { 
        $and: [ 
         {$gte: ["$ExpirationDate",today]}, 
         {$lt:["$ExpirationDate",tomorrow]} 
        ] 
       }, then: 1, else: 0 
      } 
     }, 
     ExpiringInAWeek: { 
      $cond: { if: {$gte: ["$ExpirationDate",tomorrow]}, then: 1, else: 0 } 
     } 
     } 
    }, 
    { $group: { 
     _id: 1, 
     NumberOfSubscriptionExpiringToday: {$sum: "$ExpiringToday" }, 
     NumberOfSubscriptionExpiringWithInAWeek: {$sum: "$ExpiringInAWeek" } 
    } 
    }, 
    { $project: { _id: 0 }} 
]); 

考虑也使两个简单的要求:

var numberOfSubscriptionExpiringToday = db.collection.count(
    { "ExpirationDate": { $gte: today, $lt: tomorrow }} 
); 

var numberOfSubscriptionExpiringWithInAWeek = db.collection.count(
    { "ExpirationDate": { $gte: tomorrow , $lt: weekAfterToday }} 
);