根据日期获取预订数量

时间:2019-01-21 10:30:01

标签: node.js mongodb mongoose mongodb-query aggregation-framework

如果我来自为“ 1970-01-01”,并且为“ 1970-01-05”,如何获得预订总数?

保留数组包含所有预订的房间,这些房间的日期

这是我的数据:

[
  {
    "_id": "5c0a17013d8ca91bf4ee7885",
    "name": "ABC",
    "reserved": [
      {
        "from": "1970-01-01",
        "to": "1970-01-02",
        "isCompleted": false
      },
      {
        "from": "1970-01-03",
        "to": "1970-01-05",
        "isCompleted": false
      },
      {
        "from": "2017-04-18",
        "to": "2017-04-23",
        "isCompleted": false
      },
      {
        "from": "2018-01-29",
        "to": "2018-01-30",
        "isCompleted": false
      }
    ]
  }
]

我尝试使用查找查询获取数据(我知道这是不正确的)

db.collection.find({
  reserved: {
    $not: {
      $elemMatch: {
        from: {
          $lt: "1970-01-07"
        },
        to: {
          $gt: "1970-01-05"
        },
        "isCompleted": true
      }
    }
  }
})

2 个答案:

答案 0 :(得分:2)

创建一个在过滤后的数组上利用$size运算符的管道。要进行过滤,您需要使用$filter运算符,并且条件将是$gte$lte上的AND 比较运算符,即

{ 
    "$and": [
        { "$gte": [ < from field >, "1970-01-01"] },
        { "$lte": [ < to field >, "1970-01-05"] }
    ]
}

因此,您的总体聚合操作将如下所示:

db.collection.aggregate([
    { "$addFields": {
        "totalBookings": {
            "$size": {
                "$filter": {
                    "input": "$reserved",
                    "cond": {
                        "$and": [
                            { "$gte": ["$$this.from", "1970-01-01"] },
                            { "$lte": ["$$this.to", "1970-01-05"] }
                        ]
                    }
                }                
            }
        }
    } }
])

答案 1 :(得分:1)

基本上,您需要检查这些时间跨度是否相互重叠,这意味着reserved.from <= toreserved.to >= from。要轻松处理嵌套数组,您可以从$unwind开始,然后使用$count获取匹配文档的总数,请尝试:

var from = "1970-01-01";
var to = "1970-01-05";

db.collection.aggregate([
    { $unwind: "$reserved" },
    {
        $match: { "reserved.from": { $lte: to }, "reserved.to": { $gte: from  } }
    },
    {
        $count: "total"
    }
])