java操作mongdb多条件复合查询(包括模糊查询和按时间段查询),分页


最近学了下mongdb,在这儿先和大家分享一下java操作mongdb的多条件查询,包括模糊查询,完全匹配查询和按时间段查询,以及分页。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataAccessException;
import com.channelsoft.portal.pushlog.dao.IPushLogDao;
import com.channelsoft.portal.pushlog.po.PushLogPo;
import com.channelsoft.xgPushServer.push.util.MongoUtil;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
/** 
* @author zhaocd 
* @date:2015年12月23日 上午11:32:24 
*/
public class PushLogDaoImpl implements IPushLogDao {

	@Override
	public List query(PushLogPo po, int rows, int page) throws DataAccessException {
		List list = new ArrayList();//存储数据的list
		DBCollection newsCollection = MongoUtil.getDB().getCollection("push_log");//获得mongdb数据库的连接
		BasicDBList condList = new BasicDBList();//存放查询条件的集合
		BasicDBObject searchQuery = new BasicDBObject();//条件查询的对象
		Pattern pattern;//用在模糊查询得时候,对字段进行匹配
		if(StringUtils.isNotBlank(po.getTitle())){//模糊查询
			pattern = Pattern.compile("^.*"+po.getTitle()+".*$", Pattern.CASE_INSENSITIVE);
			searchQuery.put("title",pattern);
			condList.add(searchQuery);//将这个查询条件放到条件集合中
		}
		if(StringUtils.isNotBlank(po.getSendId())){//精确匹配
			 searchQuery.put("send_id",""+po.getSendId()+"");
			 condList.add(searchQuery);//将这个查询条件放到条件集合中
		}
		if(StringUtils.isNotBlank(po.getUserIds())){//精确匹配
			 searchQuery.put("user_ids",""+po.getUserIds()+"");
			 condList.add(searchQuery);//将这个查询条件放到条件集合中
		}
		if(StringUtils.isNotBlank(po.getPushType())){//精确匹配
			 searchQuery.put("push_type",""+po.getPushType()+"");
			 condList.add(searchQuery);//将这个查询条件放到条件集合中
		}
		if(StringUtils.isNotBlank(po.getMessageType())){//精确匹配
			searchQuery.put("message_type",""+po.getMessageType()+"");
			 condList.add(searchQuery);//将这个查询条件放到条件集合中
		}
		//查询某个时间段
		searchQuery.put("create_time", BasicDBObjectBuilder.start("$gte", po.getStartTime()+" 00:00:00").add("$lte", po.getEndTime()+" 23:59:59").get());
		condList.add(searchQuery);//将这个查询条件放到条件集合中

		DBCursor cursor;//对查询结果的接受
		BasicDBObject condition= new BasicDBObject();//最后在将查询结果放到一个查询对象中去
		condition.put("$and", condList);//多条件查询使用and
		//这儿的  .skip((page - 1) * rows).limit(rows)  就是分页查询,skip()中的参数是从第多少条记录开始,limit()中的参数是一次查询多少条
		cursor = newsCollection.find(condition).skip((page - 1) * rows).limit(rows);
		po.setTotalPage(newsCollection.find(condition).count());//得到所有的符合条件的数据,用于前端显示共有多少页
		while (cursor.hasNext())
		{
			PushLogPo plog = new PushLogPo();
			DBObject DBObject = cursor.next();
			@SuppressWarnings("unchecked")
			Map map = (Map) DBObject.toMap();
			if(map.size() > 0){//对结果集的匹配
				plog.setSequence(String.valueOf(map.get("sequence")));
				plog.setSendId(String.valueOf(map.get("send_id")));
				plog.setUserIds(String.valueOf(map.get("user_ids")));
				plog.setTitle(String.valueOf(map.get("title")));
				plog.setContent(String.valueOf(map.get("content")));
				plog.setPushType(String.valueOf(map.get("push_type")));
				plog.setMessageType(String.valueOf(map.get("message_type")));
				plog.setPushResult(String.valueOf(map.get("push_result")));
				plog.setPushResult(String.valueOf(map.get("push_result")));
				plog.setPushResultCode(String.valueOf(map.get("push_result_code")));
				plog.setPushCount(String.valueOf(map.get("push_count")));
				plog.setCreateTime(String.valueOf(map.get("create_time")));
				plog.setUpdateTime(String.valueOf(map.get("update_time")));
				list.add(plog);
			}
		}
		return list;
	}
}

IPushLogDao类是自己定义的接口,在这就不展示了。


注意:在这我需要说明一下mongdb中的时间格式,之前我做入库的时候,时间入库直接是new Date()这种方式,这样入库以后在数据库中看时间格式的时候是这样的"create_time" : ISODate("2015-12-24T07:43:19.167Z") ,然后我在按条件查询得时候发现查询出来的时间格式又是这样的create_time=Thu Dec 24 15:43:19 CST 2015 ,第一个想法就是对这个时间格式进行转换,但那样就不能按时间段来查询了,所以最后就更改了时间入库的格式,把之前的new Date()改成

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    sdf.format(new Date())  这样之后,你就会发现数据库中的时间显示的格式也变了"create_time" : "2015-12-28 10:09:58" ,就没有isodate那个标志了,这样这样查询出来的时间就没问题了,就可以直接按照时间段来查询了。

你可能感兴趣的:(java)