从数组中查找 MongoDB 中仅一个日期的值
Find values from MongDB from an array for only one date
我知道 SO 中有一个类似的问题,但我的问题略有不同 。我正在试用酒店预订应用程序。我在这里存储有关房间预订日期的信息,这意味着房间在所有其他日期都可用。我正在与 mongodb
和 python
.
合作
我正在使用 $nin
函数。我有一个称为备用日期的选项,用户可以在其中输入另一个日期。我只想显示一天的空房情况,也就是说,如果第一个日期有空房,则搜索应该停止,否则应该继续到下一个日期,并在有空房的情况下给出结果。
此解决方案给出了所有给定日期的结果。
存储的数据是
{
"_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"}
您需要使用.aggregate()
方法。
您将需要使用 $match
operator to select document where the "Booked Date" is in your "date_list" then use the $project
operator to return the the "Room No" and the corresponding list of "available date" using the $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
operator then $sort
your result by "available_date" in ascending order. From there you will need to $group
your document by "Room No" and use the $first
运算符将 "available_date" 数组或列表非规范化为 return 每个文档的第一个日期。
如您所见,这会给服务器带来更多不必要的工作,因此不是一个好的解决方案。
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'}]
我知道 SO 中有一个类似的问题,但我的问题略有不同 mongodb
和 python
.
我正在使用 $nin
函数。我有一个称为备用日期的选项,用户可以在其中输入另一个日期。我只想显示一天的空房情况,也就是说,如果第一个日期有空房,则搜索应该停止,否则应该继续到下一个日期,并在有空房的情况下给出结果。
此解决方案给出了所有给定日期的结果。
存储的数据是
{
"_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"}
您需要使用.aggregate()
方法。
您将需要使用 $match
operator to select document where the "Booked Date" is in your "date_list" then use the $project
operator to return the the "Room No" and the corresponding list of "available date" using the $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
operator then $sort
your result by "available_date" in ascending order. From there you will need to $group
your document by "Room No" and use the $first
运算符将 "available_date" 数组或列表非规范化为 return 每个文档的第一个日期。
如您所见,这会给服务器带来更多不必要的工作,因此不是一个好的解决方案。
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'}]