我知道SO中有类似的问题,但我的情况略有不同Find values in mongdb。我正在尝试酒店预订应用程序。在这里,我存储有关房间预订日期的信息,这意味着房间在所有其他日期都可用。我正在使用mongodb
和python
。
我正在使用$nin
功能。我有一个名为备用日期的选项,用户在另一个日期提供。我想显示只有一天的可用性,即如果第一个日期有空房,则搜索应该停止,如果不是,它应该继续到下一个日期并给出结果(如果可用)。
此解决方案给出了所有给定日期的结果。 solution of Find values in mongdb
存储的数据是
{
"_id" : ObjectId("5645f0443f32df13e0dc786e"),
"Booked Date" : ["28-9-2015","29-9-2015","1-10-2015"],
"Room No.": "101"
},
{
"_id" : ObjectId("5645f0c73f32df062064a0f6"),
"Booked Date" : ["29-9-2015","1-10-2015"],
"Room No.": "102"
},
{
"_id" : ObjectId("5645f0c73f32df06205874f8"),
"Booked Date" : ["29-9-2015","1-10-2015","2-10-2015"],
"Room No.": "103"
},
我像这样进行查询
db.booking.find({"Date": { '$nin':[Date]}},{"_id": False,"Booked Date": False})
这里我将输入设为["1-10-2015","2-10-2015"]
因此,当我得到结果时,我不知道房间可用的日期。
有没有办法可以解决这个问题。
当我运行此代码时
db.booking.find({"Date": { '$nin':["1-10-2015","2-10-2015"]}},{"_id": False,"Booked Date": False})
我得到了结果
{"Room No.": "101"},
{"Room No.": "102"}
但我不知道这个房间的日期。在上述情况下,它仅在2-10-2015
上可用。
有没有办法说它可以在2-10-2015
上找到。
另一个案例:
db.booking.find({"Date": { '$nin':["1-10-2015","2-10-2015", "3-10-2015"]}},{"_id": False,"Booked Date": False})
此处可在2-10-2015 & 3-10-2015
上找到,但它应仅显示第一个可用日期,即2-10-2015
。
输出应与上述相同:
{"Room No.": "101"},
{"Room No.": "102"}
答案 0 :(得分:0)
您需要使用.aggregate()
方法。
您需要使用$match
运算符选择“预订日期”在“date_list”中的文档,然后使用$project
运算符返回“房间号”和相应的使用$setDifference
运算符列出“可用日期”。
然后您需要的只是处理作业客户端的其余部分。
from pprint import pprint
date_list = ["1-10-2015","2-10-2015", "3-10-2015"]
cur = collection.aggregate([
{"$match": {"Booked Date": {"$in": date_list}}},
{"$project": {
"Room No": 1,
"available_date": {
"$setDifference": [date_list, "$Booked Date"]
}
}}
])
然后使用pprint.pprint
打印结果:
pprint(list(cur))
产生:
[{'Room No': '101',
'_id': ObjectId('5645f0443f32df13e0dc786e'),
'available_date': ['2-10-2015', '3-10-2015']},
{'Room No': '102',
'_id': ObjectId('5645f0c73f32df062064a0f6'),
'available_date': ['2-10-2015', '3-10-2015']},
{'Room No': '103',
'_id': ObjectId('5645f0c73f32df06205874f8'),
'available_date': ['3-10-2015']}]
现在采用另一种效率较低的方法是,您可以使用$unwind
运算符对“available_date”数组或列表进行非规范化,然后使用$sort
结果按“available_date”升序。从那里您需要$group
您的文档“Room No”,并使用$first
运算符返回每个文档的第一个日期。
正如您所看到的那样,这对服务器来说是一项不必要的工作,因此不是一个好的解决方案。
cur = collection.aggregate([
{"$match": {"Booked Date": {"$in": date_list}}},
{"$project": {
"Room No": 1,
"available_date": {
"$setDifference": [date_list, "$Booked Date"]
}
}},
{'$unwind': '$available_date'},
{'$sort': {'avalable_date': 1}},
{'$group': {
'_id': '$Room No',
'available_date': {'$first': '$available_date'}
}}
])
# pretty print the result
pprint(list(cur))
哪个收益率:
[{'_id': '102', 'available_date': '2-10-2015'},
{'_id': '101', 'available_date': '2-10-2015'},
{'_id': '103', 'available_date': '3-10-2015'}]