从SQL到MongoDB的房间预订查询

时间:2015-06-19 06:33:10

标签: mongodb mongodb-query spring-data-mongodb

我正在研究基于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查询的结果返回。

聚合更适合这个问题吗?如果是这样,如何使用聚合操作来解决这个问题?

1 个答案:

答案 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)
        )
    );