近期遇到了一个比较麻烦的查询,就想用mongodb system.js实现,有点类似关系型数据库的存储过程的味道。
system.js是每个数据库都会有的一个特殊集合,用来存放js的变量,可以在db.eval,mapreduce,where多个地方全局调用,比较方便。
下面是mongodb脚本和java 调用部分代码:
db.system.js.remove({_id:"calculateIdleRoomByTime"}); // 这个可以将正常的会议室查询出来,但是自己实现Java Bson to JavaBean的部分,比较麻烦 db.system.js.<strong><span style="color:#009900;">insert</span></strong>({_id:"calculateIdleRoomByTime",value:function(startTime,endTime){ var roomIds = [], rooms = []; // 根据时间将被占用的会议室编号查询出来 var cursor = db.conference.find({isDel:false,$or:[ {beginTime:{$gte:startTime},endTime:{$lte:endTime}}, {$or:[ // 开始时间不在区间内 {beginTime:{$lt:startTime},endTime:{$gt:startTime}}, // 结束时间不在区间内 {beginTime:{$lt:endTime},endTime:{$gt:endTime}} ] } ]}); while(cursor.hasNext()){ var _conference = cursor.next(); if(_conference.location){ roomIds.push(_conference.location.$id); } } // read idle rooms cursor = db.conferenceRoom.find({_id:{$nin:roomIds}}); while(cursor.hasNext()){ rooms.push(cursor.next()); } return rooms; }}); // 正式环境使用的是这个,查询被占用的会议室编号。然后Java Driver 使用$nin查询出正常的会议室 db.system.js.insert({_id:"calculateNotIdleRoomIdsByTime",value:function(startTime,endTime){ var roomIds = [], rooms = []; // 根据时间将被占用的会议室编号查询出来 var cursor = db.conference.find({isDel:false,$or:[ {beginTime:{$gte:startTime},endTime:{$lte:endTime}}, {$or:[ // 开始时间不在区间内 {beginTime:{$lt:startTime},endTime:{$gt:startTime}}, // 结束时间不在区间内 {beginTime:{$lt:endTime},endTime:{$gt:endTime}} ] } ]}); while(cursor.hasNext()){ var _conference = cursor.next(); if(_conference.location){ roomIds.push(_conference.location.$id); } } return roomIds; }}); db.eval("calculateIdleRoomByTime(8,9)"); db.eval("calculateNotIdleRoomIdsByTime(2,14)"); // 简单例子 db.system.js.insert({_id:"max",value:function(a,b){return a>b?a:b;}}); db.eval("max(2,399)"); // 399
/** * 根据时间查询空闲会议室 * @author Bill * @since V.10 2015年4月21日 - 上午10:03:57 * @param startTime * @param endTime * @return */ @SuppressWarnings("unchecked") public List<ConferenceRoom> findByTime(long startTime, long endTime) { <span style="color:#009900;">Object result = mongoTemplate.getDb().eval("calculateNotIdleRoomIdsByTime("+startTime+","+endTime+")");</span> DBObject callResult = (DBObject) JSON.parse(JSON.serialize(result)); Set<Entry<String, ObjectId>> notIdleRoomIdSets = callResult.toMap().entrySet(); List<ObjectId> notIdleRoomIds = new ArrayList<ObjectId>(); for (Entry<String, ObjectId> entry : notIdleRoomIdSets) { notIdleRoomIds.add(entry.getValue()); } BasicQuery bq = new BasicQuery( new BasicDBObject("isDel", false) .append("_id", new BasicDBObject("$nin", notIdleRoomIds)) ); return find(bq); }
原文:http://blog.csdn.net/u010811257/article/details/45168673