我正在研究基于MongoDB的会议室预订应用程序。我有商业实体:
class Room {
private String id;
// ...
}
class RoomReservation {
private String id;
private String room_id;
private String user_id;
private Date start;
private Date end;
// ...
}
要查找给定时间段(开始,结束)中的任何可用会议室,如果我使用关系数据库,我可以进行类似以下的查询。
select * from room as r where r.id not in (
select room_id from room_reservation as rr
where (rr.start <= start and rr.end >= start)
union
select room_id from room_reservation as rr
where (rr.start <= end and rr.end >= end)
union
select room_id from room_reservation as rr
where (rr.start >= start and rr.end <= end)
union
select room_id from room_reservation as rr
where (rr.start <= start and rr.end >= end)
)
我可以为MongoDB提供类似的查询语句。然而,这种方法不会很有效。与SQL语句中返回的单个字段(整个文档数据)不同,RoomReservation需要作为MongoDB查询的结果返回。
聚合更适合这个问题吗?如果是这样,如何使用聚合操作来解决这个问题?
答案 0 :(得分:1)
除非我在这里遗漏了一些东西,否则联盟查询在这里甚至有点过分。实质上,这要求每个条件集中包含的项目不是从集合中获得的结果的一部分。
这是MongoDB中的$nor
运算符,它确保在选择文档时不会满足指定的条件。
本质上结构是这样的:
db.collection.find({
"$nor": [
{ "start": { "$lte": start }, "end": { "$gte": start } },
{ "start": { "$lte": end }, "end": { "$gte": end } },
{ "start": { "$gte": start }, "end": { "$lte": end } },
{ "start": { "$lte": start }, "end": { "$gte": end } }
]
})
在不启动IDE的情况下不确定辅助方法的构造,但是这里的运算符应该是您通常要查找的查询结构。
-
使用spring数据中的辅助方法:
Query query = new Query().addCriteria(
new Criteria().norOperator(
Criteria.where("start").lte(start).and("end").gte(end),
Criteria.where("start").lte(end).and("end").gte(end),
Criteria.where("start").gte(start).and("end").lte(end),
Criteria.where("start").lte(start).and("end").gte(end)
)
);