MongoDB $或vs $匹配聚合,并进行大量日期比较

时间:2017-04-18 06:09:22

标签: javascript mongodb mongodb-query aggregation-framework

我需要计算4月份发生的所有预订以及4月份的预订天数。 我知道如何做到这一点的唯一方法是进行4个不同的MongoDB查找并通过每个查找循环并在JS中手动计数 (selectBooking是mongoDB的结果,现在我只找到数据库中的所有预订,但这真的很慢!)

所以我的问题是 - 这可以用更聪明的方式完成吗?

var startOfMonth = new Date("2017-04-01 00:00:00") / 1000;
var endOfMonth = new Date("2017-04-30 23:23:59") / 1000;

// If booking is INSIDE this month 
//    [ooooooooooooooooooooooooooooo]  <-- This month 
//           [xxxxxxxxxxxxxxxx]        <-- The booking
var selectBooking = bookingArray.filter(function(obj){
    return (obj.checkin >= startOfMonth && obj.checkout <= endOfMonth)
})
for (var b=0; b<selectBooking.length; b++) {    
    totalBookings++;
    totalDays += daysBetween(new Date(selectBooking[b].checkin*1000),new Date(selectBooking[b].checkout*1000))
}

// If booking COVERS the whole month
//    [oooooooooooooooooooooooooooo]    <-- This month 
// [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] <-- The booking
var selectBooking = bookingArray.filter(function(obj){
    return (obj.checkin < startOfMonth && obj.checkout > endOfMonth)
})
for (var b=0; b<selectBooking.length; b++) {    
    totalBookings++;
    totalDays += daysBetween(new Date(startOfMonth*1000),new Date(endOfMonth*1000))
}

// If booking is BEGINNING before this month but ENDING in this month
//       [ooooooooooooooooooooooooooo]  <-- This month 
// [xxxxxxxxxxxxxxxx]                   <-- The booking
var selectBooking = bookingArray.filter(function(obj){
    return (obj.checkin < startOfMonth && obj.checkout > startOfMonth)
})
for (var b=0; b<selectBooking.length; b++) {    
    totalBookings++;
    totalDays += daysBetween(new Date(startOfMonth*1000),new Date(selectBooking[b].checkout*1000))
}

// If booking is BEGINING in this month but ENDING after this month
//   [ooooooooooooooooooooooooooo]      <-- This month 
//                   [xxxxxxxxxxxxxxxx] <-- The booking
var selectBooking = bookingArray.filter(function(obj){
    return (obj.checkin < endOfMonth && obj.checkout > endOfMonth)
})
for (var b=0; b<selectBooking.length; b++) {    
    totalBookings++;
    totalDays += daysBetween(new Date(selectBooking[b].checkin*1000),new Date(endOfMonth*1000))
}

我试过这个,但得到错误: &#34;匹配过滤器必须是对象中的表达式&#34;

db.getCollection("booking").aggregate([
    { $match: 
        [
            { checkin: {$gte: 1490979600}, checkout: {$lte: 1493569439} },
            { checkin: {$lt:  1490979600}, checkout: {$gt:  1493569439} },
            { checkin: {$lt:  1490979600}, checkout: {$gt:  1490979600} },
            { checkin: {$lt:  1493569439}, checkout: {$gt:  1493569439} }
        ]
    },
    {
        $project:{
            "_id" : 0,
            "checkin" : 1,
            "checkout" : 1
        }
    }   
])

我也试过这个,但得到错误: &#34;无法识别的管道阶段名称:&#39; $或&#39;&#34;

db.getCollection("booking").aggregate([
    { $or: 
        [
            { checkin: {$gte: 1490979600}, checkout: {$lte: 1493569439} },
            { checkin: {$lt:  1490979600}, checkout: {$gt:  1493569439} },
            { checkin: {$lt:  1490979600}, checkout: {$gt:  1490979600} },
            { checkin: {$lt:  1493569439}, checkout: {$gt:  1493569439} }
        ]
    },
    {
        $project:{
            "_id" : 0,
            "checkin" : 1,
            "checkout" : 1
        }
    }   
])

我在报告中使用了很多。 预订(如此处),费用,发票等等.... 我以同样糟糕的方式做到这一切。

希望有人可以找到更好的方法: - )

(对不起,长篇文章)

1 个答案:

答案 0 :(得分:1)

你需要使用$ match with $或like like

db.getCollection("booking").aggregate([
    {
        $match:
        { 
            $or: 
            [
                { checkin: {$gte: 1490979600}, checkout: {$lte: 1493569439} },
                { checkin: {$lt:  1490979600}, checkout: {$gt:  1493569439} },
                { checkin: {$lt:  1490979600}, checkout: {$gt:  1490979600} },
                { checkin: {$lt:  1493569439}, checkout: {$gt:  1493569439} }
            ]
        }
    },
    {
        $project:{
            "_id" : 0,
            "checkin" : 1,
            "checkout" : 1
        }
    }   
])