$match 用于过滤日期的回溯

$match for filtering backtracking of dates

我正在尝试创建一个将使用一个日期参数的 $match,它可以进行日期回溯。我想要实现的是根据将要使用的过滤器获取所有被占用的房间。请看下面的场景。

原始数据

{
    "_id" : ObjectId("60d9681765077a71ae158625"),
    "room": "301",
    "startaccomodation":ISODate("2021-08-05T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-10T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dbf391e2759909d52d1917"),
    "room": "302",
    "startaccomodation":ISODate("2021-08-07T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-09T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dbf61d54b7c46bfa1b7954"),
    "room": "303",
    "startaccomodation":ISODate("2021-08-02T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-05T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dbf6ef6a9e0e09f9a4caa6"),
    "room": "304",
    "startaccomodation":ISODate("2021-08-06T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-08T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dbf6ef5805b16bf96286cc"),
    "room": "305",
    "startaccomodation":ISODate("2021-08-01T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-05T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dd0d7b1410931155f0bdd0"),
    "room": "306",
    "startaccomodation":ISODate("2021-08-02T06:11:36.007Z"),
    "endaccomodation":null
},
{
    "_id" : ObjectId("60dd0e04c02ff023ab091cd3"),
    "room": "307",
    "startaccomodation":ISODate("2021-08-06T06:11:36.007Z"),
    "endaccomodation":null
}

如果我只想得到所有在 2021 年 8 月 3 日被占用的房间。输出将是:

{
    "_id" : ObjectId("60dbf61d54b7c46bfa1b7954"),
    "room": "303",
    "startaccomodation":ISODate("2021-08-02T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-05T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dbf6ef5805b16bf96286cc"),
    "room": "305",
    "startaccomodation":ISODate("2021-08-01T06:11:36.007Z"),
    "endaccomodation":ISODate("2021-08-05T06:11:36.007Z")
},
{
    "_id" : ObjectId("60dd0d7b1410931155f0bdd0"),
    "room": "306",
    "startaccomodation":ISODate("2021-08-02T06:11:36.007Z"),
    "enddate": null
},

如果我将筛选器放在今天,这将提供截至目前已入住的所有房间的数据。输出将是:

{
    "_id" : ObjectId("60dd0d7b1410931155f0bdd0"),
    "room": "306",
    "startaccomodation":ISODate("2021-08-02T06:11:36.007Z"),
    "endaccomodation":null
},
{
    "_id" : ObjectId("60dd0e04c02ff023ab091cd3"),
    "room": "307",
    "startaccomodation":ISODate("2021-08-06T06:11:36.007Z"),
    "endaccomodation":null
}

我的匹配不完整,还没有数据输出。

{
  $match: {
    $and: [
      {
        "startdate": {
          "$gte": ISODate("2021-08-03T00:00:00.000Z"),
          
        }
      },
      {
        "enddate": {
          "$lte": ISODate("2021-08-03T00:00:00.000Z"),
           
        }
      },
        
    ]
  }
}

提前致谢。

我认为你颠倒了日期范围逻辑。

应该是:

startaccomodation <= x <= endaccomodation

虽然有 endaccomodationnull,但第二个条件应该以 $or 开始,满足以下任一条件:

  1. endaccomodation 为空
  2. endaccomodation 必须是 $gte 输入的日期。
db.collection.aggregate([
  {
    $match: {
      $and: [
        {
          "startaccomodation": {
            "$lte": ISODate("2021-08-03T00:00:00.000Z")
          }
        },
        {
          $or: [
            {
              "endaccomodation": {
                $eq: null
              }
            },
            {
              "endaccomodation": {
                "$gte": ISODate("2021-08-03T00:00:00.000Z")
              }
            }
          ]
        }
      ]
    }
  }
])

Sample Mongo Playground