【问题标题】:How to query for objects between date ranges如何查询日期范围之间的对象
【发布时间】:2015-01-12 23:35:52
【问题描述】:

我在 mongodb 集合中有如下文档:

 "listingReservation" : {
    "reservationFromDate" : new Date("14.1.2015 00:00:00"),
    "reservationToDate" : new Date("17.1.2015 00:00:00"),
    "reservationCreatedBy" : "test@test.com",
    "reservationCreatedOn" : "",
    "reservationChangedBy" : "",
    "reservationChangedOn" : "",
    "reservationStatus" : "pending"  //status can be pedning, accepted or rejected  
  }

现在,当管理员接受预订时,相同日期范围内的其他预订和包含已接受预订的预订应设置为拒绝状态。

现在我如何才能找到在新的预订日期之间是否已经存在预订对象,或者是否已经存在新预订日期的包含预订。

我尝试了以下查询,但显然所有条件都不起作用。

db1.reservationTable.update(
            {
                $and: [{
                    $or: [{

                        $or: [
                            {
                                'listingReservation.reservationFromDate': {
                                    $gte: new Date(req.body.listingReservation.reservationFromDate),
                                    $lt: new Date(req.body.listingReservation.reservationToDate)
                                }
                            },
                            {
                                'listingReservation.reservationToDate': {
                                    $gte: new Date(req.body.listingReservation.reservationFromDate),
                                    $lt: new Date(req.body.listingReservation.reservationToDate)
                                }
                            }
                        ],
                        $and: [
                            {'listingReservation.reservationFromDate': {$lte: new Date(req.body.listingReservation.reservationFromDate)}},
                            {'listingReservation.reservationToDate': {$gte: new Date(req.body.listingReservation.reservationToDate)}}
                        ]
                    }]
                },
                    {'listingBasics.listingId': req.body.listingBasics.listingId},
                    {_id: {$ne: mongojs.ObjectId(req.body._id)}},
                    {'listingBasics.listingOwner': req.user.username}
                ]
            },
            {
                $set: {'listingReservation.reservationStatus': 'rejected'}
            })

【问题讨论】:

    标签: mongodb mongodb-query mongojs


    【解决方案1】:

    如果我对问题的理解正确,您正在寻找一个查询来查找是否有任何预订与日期范围重叠,并将这些预订的状态设置为rejected。就您的设置而言,执行此操作的标准查询是

    db1.reservationTable.update({ 
            "reservationFromDate" : { "$lte" : new Date(req.body.listingReservation.reservationToDate) },            
            "reservationToDate" : { "$gte" : new Date(req.body.listingReservation.reservationFromDate) } 
        }, 
        { "$set" : { "reservationStatus" : "rejected" } }, 
        { "multi" : true }
    )
    

    如果我们将测试重叠的时间段称为TS,简单的英语条件是TS 结束之前开始,TS 开始之后结束。如果您考虑一下,您会发现这保证了TS 重叠。

    【讨论】:

    • 这确实涵盖了所有的逻辑基础。我不确定为什么找不到这个简化的查询表单。做得很好!
    • @Wdberkeley,非常感谢,完美运行,非常优雅。
    【解决方案2】:

    要问的合乎逻辑的问题是

    是否有任何保留:

    开始日期在req.body.listingReservation.reservationFromDate之前并且结束日期在req.body.listingReservation.reservationFromDate之后

    开始日期在req.body.listingReservation.reservationToDate之前并且结束日期在req.body.listingReservation.reservationToDate之后

    开始日期在req.body.listingReservation.reservationFromDate之后并且结束日期在req.body.listingReservation.reservationToDate之前?

    这是基于您的可能的查询:

    db1.reservationTable.update(
      {
        $or: [
          {
            'listingReservation.reservationFromDate': {
              $lte: new Date(req.body.listingReservation.reservationFromDate)
            }, 'listingReservation.reservationToDate': {
              $gte: new Date(req.body.listingReservation.reservationFromDate)
            }
          }, {
            'listingReservation.reservationFromDate': {
              $lte: new Date(req.body.listingReservation.reservationToDate)
            }, 'listingReservation.reservationToDate': {
              $gte: new Date(req.body.listingReservation.reservationToDate)
            }
          }, {
            'listingReservation.reservationFromDate': {
              $gte: new Date(req.body.listingReservation.reservationFromDate)
            }, 'listingReservation.reservationToDate': {
              $lte: new Date(req.body.listingReservation.reservationToDate)
            }
          }
        ],
        'listingBasics.listingId': req.body.listingBasics.listingId,
        _id: {$ne: mongojs.ObjectId(req.body._id)},
        'listingBasics.listingOwner': req.user.username
      }, {
        $set: {'listingReservation.reservationStatus': 'rejected'}
      })
    

    【讨论】:

    • 感谢您的回答,但这里的一个条件仍未满足,我正在努力了解如何将其合并。下面是我测试的场景,我的预订看起来像这样(开始-结束)-(14 到 17)、(18-19)、(23-25)和(15-20)。现在接受(14-17)拒绝(18-19)和(15-20)。接受 (18-19) 拒绝 (15-20) 这两种情况都是正确的。但是接受(15-20)只会拒绝(14-17),我什至希望(18-19)被拒绝。这是因为mongodb吗?因为正如我从您的逻辑问题中读到的那样,所有条件都应涵盖。
    • P.S:我已经投票赞成答案,但这仍然不是完整的答案;)
    • 您能否提供问题中的实际样本数据?一个简单的db1.reservationTable.find(),并编辑了任何敏感数据?
    猜你喜欢
    • 1970-01-01
    • 2014-06-13
    • 2021-04-07
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多