我有许多文档,模式如下所示,每个文档都包含(开始日期、结束日期),如下面的模式所示。在保存新文档之前,是否有一种简单的方法可以知道新文档是否开始日期、结束日期将与以前保存的文档日期重叠?谢谢
{
"title" : "",
"owner" : "",
"notes" : "",
"startdate" : "",
"enddate" : ""
}以下是目前保存的唯一文档:
Document.(anonymous function) {_id: "FADnPAxRu4Ps5hkLz",
title: "Round A",
customerid: "QDGvBQhS6vYgZtnRr",
startdate: "11/21/2014 7:25 AM"…}
_id: "FADnPAxRu4Ps5hkLz"customerid: "QDGvBQhS6vYgZtnRr"
enddate: "11/30/2014 6:09 AM"
startdate: "11/21/2014 7:25 AM"
title: "Round A"__proto__: Document.(anonymous function)当我尝试对上面的文档执行以下任何查询时,它都不会返回任何内容,尽管这里有明显的重叠。
db.Projects.find({'startdate': {$lt: '11/25/2014 6:26 PM'}, 'enddate': {$gt: '11/19/2014 6:26 PM'}}, {sort:{time: -1}});
db.Projects.find({'startdate': {$lt: '11/30/2014 6:26 PM'}, 'enddate': {$gt: '11/21/2014 6:26 PM'}}, {sort:{time: -1}});发布于 2014-11-12 01:20:03
下面的图可以用这4种情况说明时间重叠,其中S/E是新文档的开始/结束日期,而S'/E‘是任何现有文档的开始日期/结束日期:
S' E'
|-------------------|
S E
|****************|
S' E'
|-----------|
S' E'
|-----------|
S' E'
|-----------|4例出现S'<E和E'>S。查找所有重叠时间的文档的查询可以是:
db.collection.find({"startdate": {"$lt": E}, "enddate": {"$gt": S}})编辑:
开始日期和结束日期是字符串格式的,而不是按词汇顺序排列的,因此不能使用"$gt“和"$lt”进行比较。您应该将它们转换为日期类型:
db.collection.find().forEach(
function (e) {
// convert date if it is a string
if (typeof e.startdate === 'string') {
e.startdate = new Date(e.startdate);
}
if (typeof e.enddate === 'string') {
e.enddate = new Date(e.enddate);
}
// save the updated document
db.collection.save(e);
}
)最后的查询是:
db.collection.find({"startdate": {"$lt": new Date("E")}, "enddate": {"$gt": new Date("S")}})发布于 2022-04-09 17:49:46
在被接受的答案的帮助下,我能够将所有四个案例融合在一起,并想出了一个完美的解决方案。希望它能帮到别人。
S E
|****************|
S1 E1
|----------------------|
S2 E2
|----------|
S3 E3
|-----------|
S4 E4
|-------------|案例1:间隔完全涵盖开始日期和结束日期
{ "startDate": { $lte: moment(S1).toDate() } }
{ "endDate": { $gte: moment(E1).toDate() } }案例2:间隔完全在开始日期和结束日期内。
{ "startDate": { $gte: moment(S2).toDate() } }
{ "endDate": { $lte: moment(E2).toDate() } }案例3:开始日期在间隔之外,结束日期在间隔内。
{ "endDate": { $gte: moment(S3).toDate() } }
{ "endDate": { $lte: moment(E3).toDate() } }案例4:开始日期在间隔内,结束日期在间隔之外。
{ "startDate": { $gte: moment(S4).toDate() } }
{ "startDate": { $lte: moment(E4).toDate() } }将这四种情况与“$and”和“$or”结合起来,就可以得到至少满足一种情况的数据。
const query = {};
const datePipeArray = [];
datePipeArray.push({ "$and":[
{ "startDate": { $gte: moment(queryStartDate).toDate() } },
{ "endDate": { $lte: moment(queryEndDate).toDate() } }
]});
datePipeArray.push({ "$and":[
{ "endDate": { $gte: moment(queryStartDate).toDate() } },
{ "endDate": { $lte: moment(queryEndDate).toDate() } }
]});
datePipeArray.push({ "$and":[
{ "startDate": { $gte: moment(queryStartDate).toDate() } },
{ "startDate": { $lte: moment(queryEndDate).toDate() } }
]});
datePipeArray.push({ "$and":[
{ "startDate": { $lte: moment(queryStartDate).toDate() } },
{ "endDate": { $gte: moment(queryEndDate).toDate() } }
]});
query["$or"] = datePipeArray;
db.calendar.find(query)P.S:时刻是可选的
https://stackoverflow.com/questions/26876803
复制相似问题