如何搜索和查找符合其他集合标准的父文档

时间:2016-05-06 07:36:51

标签: mongodb meteor mongodb-query

我使用meteor和mongo db

我有两个具有一对多结构的集合

酒店:

{
    _id:1,
    name: "Hotel 1"
},
{
    _id:2,
    name: "Hotel 2"
}

预订

{_id:1,
    hotel_id_:1,
    date: "2016-05-06",
    num_nights: 2,
    dates: ["2016-05-06", "2016-05-06"]
},
{_id:2,
    hotel_id:1
    date: "2016-05-04",
    num_nights: 1,
    dates: ["2016-05-04"]
},
{_id:3,
    hotel_id:2
    date: "2016-05-01",
    num_nights: 3,
    dates: ["2016-05-01", "2016-05-02", "2016-05-03"]
}

我还可以保存这样的酒店,预订是父母的直接孩子:

{
    _id:1,
    name: "Hotel 1",
    bookings:[
        {_id:1,
            hotel_id_:1,
            date: "2016-05-06",
            num_nights: 2,
            dates: ["2016-05-06", "2016-05-06"]
        },
        {_id:2,
            hotel_id:1
            date: "2016-05-04",
            num_nights: 1,
            dates: ["2016-05-04"]
        }
    ]
}

我正试图找到一种方法,可以根据任何特定日期的3条标准找到酒店

  • 城市名称(正则表达式 - 我可以管理这个)
  • 可用性(由酒店给出 - 我可以管理)
  • 在给定日期没有冲突预订

编辑:

酒店和预订是我实际设置的隐喻,但它们非常相似。 假设某个酒店在某个特定日期预订或未预订没有'客房'

/编辑

我可以找到给定酒店的预订,但我不知道如何将整个酒店结合起来找到满足前两个要求的酒店,但也没有碰撞预订,因为目前的预订是在单独的集合

有没有办法找到符合前两个标准的酒店,然后过滤掉那些不符合第二个条件的酒店 - 无需手动循环遍历每个文件

谢谢!我很乐意进一步澄清。

2 个答案:

答案 0 :(得分:1)

由于没有给出容量,看起来预订仍然存在问题。 在这种情况下,我们不希望客户在三个不同的房间预订三晚 - 所以这应该作为酒店的详细信息提供。 为了简化我们只能使用容量(房间或人员/房间的组合),我们将能够为客户提供有关可用性的信息。

hotel {
    id : 1,
    roomsCount : 200
}

bookings {
    id : 1,
    hotelId : 1,
    roomsTaken : 1
    date : [201605-05, 2016-05-06]
}, {
    id : 2,
    hotelId : 1,
    roomsTaken : 3
    date : [2016-05-06, 2016-05-07]
}, {
    id : 1,
    hotelId : 1,
    roomsTaken : 10
    date : [2016-05-05, 2016-05-06, 2016-05-07]
}

如果我们在2015-05-06有4个房间,我们想要讨价还价

db.bookings.aggregate([{
            $match : {
                date : 2016-05-06
            }
        }, //select only bookings having this date
        {
            $unwind : date
        }, {
            $match : {
                date : 2016-05-06
            }
        }, //select only bookings having this date
        {
            $group : {
                _id : null,
                roomsTaken : {
                    $sum : "$roomsTaken"
                }
            }
        }
    ])

所以当我们得到多少房间时,我们可以提供多少房间免费。

作为一个延伸,我们可以有一个房间号码池,并将其标记为免费/保留/使用

答案 1 :(得分:1)

如果你添加时刻套餐(momentjs:moment),你可以检查两个日期是否有这样的冲突:

var rangeOne = moment.range(startDate, endDate);  //you should define your start and end dates
var rangeTwo = moment.range(otherStartDate, otherEndDate); //you should also define the dates here

if(rangeTwo.overlaps(rangeOne) == true) {
    //if dates conflict, do something
} else {
    //do something when dates don't conflict
}

您还可以在forEach()中使用上面的代码,因为您需要检查日期是否与任何预订冲突。如果说明不够,请使用新代码更新您的问题,并使用可用于满足您特定需求的实际代码编辑我的答案。