Java mongodb System.js 应用

近期遇到了一个比较麻烦的查询,就想用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

Java调用:

/**
	 * 根据时间查询空闲会议室
	 * @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);
	}

挺有意思 。 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。