Javascript 如何根据截止日期搜索mongodb?
使用MERN stack构建租赁清单应用程序。我的上市模式如下:Javascript 如何根据截止日期搜索mongodb?,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,使用MERN stack构建租赁清单应用程序。我的上市模式如下: const listingShcema = new mongoose.Schema( { hostedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', }, title: { type: String, required: true, }, description: {
const listingShcema = new mongoose.Schema(
{
hostedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
numberOfGuests: {
type: String,
required: true,
},
numberOfRooms: {
type: String,
required: true,
},
numberOfBeds: {
type: String,
required: true,
},
numberOfBaths: {
type: String,
required: true,
},
price: {
type: String,
requried: true,
},
location: {
streetAddress: { type: String },
city: { type: String },
state: { type: String },
postalCode: { type: String },
},
bookedDates: [
{
startDate: Date,
endDate: Date,
},
],
imgUrls: [
{
type: String,
},
],
amenities: [
{
type: String,
},
],
},
{ timestamps: true }
);
现在,对用户搜索查询提供的所有内容运行查询相当容易,除了他们想要出租的日期。列表模型跟踪所有bookedDates。我希望能够在mongodb中搜索没有与用户搜索查询提供的日期匹配的bookedDates的列表(向用户显示可用列表)。我想不出一个办法来做这个??我认为只记录预订日期很容易,而不是从所有可用日期数组中删除预订日期。直接在数据库中这样做有点尴尬,尤其是如果您只存储每个预订的
开始日期和结束日期。例如,如果有人从1号到5号预订了一个列表-如果另一个用户从3号到7号搜索同一个列表,则该列表与保存的预订不匹配,但该列表仍不会被视为可用
我建议你再看一看你的模型,甚至可以把预定的日期分到他们自己的文件中
但是,根据您所拥有的,假设您将来不会预订太远,那么将bookedDates
存储为平面阵列可能是值得的。因此,如果我们从1号到3号以及6号到8号预订了一个列表,那么您的阵列将如下所示:
bookedDates: [
'2021-01-01',
'2021-01-02',
'2021-01-03',
'2021-01-06',
'2021-01-07',
'2021-01-08'
]
然后,如果有人在2号和4号之间搜索列表,您会再次将这些日期分解为一个平面数组,然后您应该能够使用$nin
操作符():
引用本页的相关部分:
如果字段包含数组,则$nin运算符将选择其字段包含数组的文档,该数组中没有与指定数组中的值相等的元素(例如,等等)
如果您有另一种方法过滤掉大部分列表,那么这显然是最有效的,因为您没有对数据库中的每个列表进行数组检查
您还必须通过删除过去的日期来保持bookedDates
最新
另一个选项是只查询您的列表并在应用程序级别进行日期筛选,在这种情况下,您可能可以保留现有的startDate
和endDate
格式
扁平化日期更新
这样的办法应该行得通。我只是蛮力的-人们通常只会在几天内预订一个列表,所以你的循环会非常小。如果是一天,那里会有一些检查,以确保开始是在结束之前,但仅此而已
作为一种方法,您可以随时调用它,它将把两个日期分割成一个扁平的字符串数组,格式为yyy-mm-dd
格式
function getFlattenedDatesAr(inputStart, inputEnd) {
// convert to dates and make sure that start is before end
let startDate = new Date(inputStart)
let endDate = new Date(inputEnd)
if(startDate > endDate) {
let temp = startDate;
startDate = endDate;
endDate = temp;
}
// get our dates in yyyy-mm-dd format
const startDateStr = startDate.toISOString().substr(0, 10)
const endDateStr = endDate.toISOString().substr(0, 10)
// check if they've only booked for one day
if(startDateStr === endDateStr) {
return [startDateStr];
return;
}
// fill our our dates array
const bookedDates = [startDateStr]
let currDate = startDate;
while(true) {
// NOTE: setDate returns a timestamp, not a Date
const nextDateTS = currDate.setDate(currDate.getDate() + 1);
// get our date string and add it to our bookedDates array
currDate = new Date(nextDateTS)
const currDateStr = currDate.toISOString().substr(0, 10);
bookedDates.push(currDateStr);
// if our string matches our end date, we're done
if(currDateStr === endDateStr) {
break
}
}
return bookedDates
}
// assume these are the dates sent, in yyyy-mm-dd format
let inputStart = '2021-01-01'
let inputEnd = '2021-01-05'
const datesAr = getFlattenedDatesAr(inputStart, inputEnd)
console.log(datesAr);
您建议我如何获取介于两者之间的其他日期,即给定的两个期望开始日期和结束日期,以添加到BookEdates数组中?@stinny我添加了一个编辑来显示我将如何执行此操作
function getFlattenedDatesAr(inputStart, inputEnd) {
// convert to dates and make sure that start is before end
let startDate = new Date(inputStart)
let endDate = new Date(inputEnd)
if(startDate > endDate) {
let temp = startDate;
startDate = endDate;
endDate = temp;
}
// get our dates in yyyy-mm-dd format
const startDateStr = startDate.toISOString().substr(0, 10)
const endDateStr = endDate.toISOString().substr(0, 10)
// check if they've only booked for one day
if(startDateStr === endDateStr) {
return [startDateStr];
return;
}
// fill our our dates array
const bookedDates = [startDateStr]
let currDate = startDate;
while(true) {
// NOTE: setDate returns a timestamp, not a Date
const nextDateTS = currDate.setDate(currDate.getDate() + 1);
// get our date string and add it to our bookedDates array
currDate = new Date(nextDateTS)
const currDateStr = currDate.toISOString().substr(0, 10);
bookedDates.push(currDateStr);
// if our string matches our end date, we're done
if(currDateStr === endDateStr) {
break
}
}
return bookedDates
}
// assume these are the dates sent, in yyyy-mm-dd format
let inputStart = '2021-01-01'
let inputEnd = '2021-01-05'
const datesAr = getFlattenedDatesAr(inputStart, inputEnd)
console.log(datesAr);