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<PushLogPo> query(PushLogPo po, int rows, int page) throws DataAccessException { List<PushLogPo> list = new ArrayList<PushLogPo>();//儲存資料的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<String, Object> map = (Map<String, Object>) 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那個標誌了,這樣這樣查詢出來的時間就沒問題了,就可以直接按照時間段來查詢了。