morphia是谷歌的一個針對mongodb的數據化持久框架;
關於mongodb的介紹不在這里展示,直接進入主題:采用morphia實現對mongodb的聚合查詢
這里獲取所有學生的分數總和
spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" default-autowire="byName"> <bean id="mongoDBManager" class="com.snake.bsys.common.db.MongoDBManager" scope="singleton" > <property name="serverIpAddr"> <value>127.0.0.1</value> </property> <property name="serverPort"> <value>27017</value> </property> <property name="userName"> <value>用戶名</value> </property> <property name="userPsw"> <value>密碼</value> </property> <property name="connSource"> <value>庫名</value> </property> </bean> <bean id="simpleMongoDBDao" class="com.snake.bsys.common.db.SimpleMongoDBDao" scope="singleton" > <property name="dbName"> <value>庫名</value> </property> </bean> </beans> public class SimpleMongoDBDao<T> { String dbName; public String getDbName() { return dbName; } public void setDbName(String dbName) { this.dbName = dbName; } public Datastore getDB() { Datastore datastore = MongoDBManager.getDB(dbName); return datastore; } public Pagination queryForPage(Pagination pagination, Query query) { try { //每頁顯示條數 int pageSize = pagination.getPageSize(); //第幾頁 int pageCount = pagination.getPageNo(); //總記錄數 int recordCount = pagination.getTotalCount(); //獲取總記錄數 recordCount = (int) query.count(); //總記錄數 pagination.setTotalCount(recordCount); //第一條數據位置 int firstResult = pagination.getFirstResult(); firstResult = firstResult < 0 ? 0 : firstResult; FindOptions findOptions = new FindOptions(); //起始位置 findOptions.skip(firstResult); //查詢條數 findOptions.limit(pageSize); //當前頁碼 pagination.setPageNo(pagination.getPageNo()); //總頁數 pagination.setPageSize(PageHelper.getPageCount(recordCount, pagination.getPageSize())); List<T> list = query.asList(findOptions); pagination.setList(list); return pagination; } catch (Exception e) { e.printStackTrace(); Log.logger.error(e.getMessage(), e); } return null; } public T getOne(Class classT, String colName, Object equalObj) { try { Datastore datastore = this.getDB(); Query<T> query = datastore.createQuery(classT); query = query.field(colName).equal(equalObj); List<T> list = query.asList(); if (list != null && list.size() > 0) return list.get(0); } catch (Exception ex) { ex.printStackTrace(); Log.logger.error(ex.getMessage(), ex); } return null; } } public class MongoDBManager { String serverIpAddr=""; int serverPort=0; String userName=""; String userPsw=""; String connSource=""; public String getServerIpAddr() { return serverIpAddr; } public void setServerIpAddr(String serverIpAddr) { this.serverIpAddr = serverIpAddr; } public int getServerPort() { return serverPort; } public void setServerPort(int serverPort) { this.serverPort = serverPort; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPsw() { return userPsw; } public void setUserPsw(String userPsw) { this.userPsw = userPsw; } public String getConnSource() { return connSource; } public void setConnSource(String connSource) { this.connSource = connSource; } MongoClient mongoClient; Morphia morphia; private static MongoDBManager runInstance; /** * 初始化連接池 */ public void initConn() { // 其他參數根據實際情況進行添加 try { morphia = new Morphia(); // 告訴Morphia在哪里找到你的類 // 可以為不同的包或者類進行多次的調用 morphia.mapPackage(""); ServerAddress serverAddress = new ServerAddress(serverIpAddr,serverPort); List<ServerAddress> addrs = new ArrayList<ServerAddress>(); addrs.add(serverAddress); //MongoCredential.createScramSha1Credential()三個參數分別為 用戶名 數據庫名稱 密碼 MongoCredential credential = MongoCredential.createScramSha1Credential(userName, connSource, userPsw.toCharArray()); List<MongoCredential> credentials = new ArrayList<MongoCredential>(); credentials.add(credential); mongoClient = new MongoClient(addrs,credentials); runInstance=this; Log.logger.info("mongoDB 初始化完成 init OK....at:"+ DateUtil.getStandardDate(new Date())); } catch (Exception e) { e.printStackTrace(); Log.logger.error("mongoDB 失敗,"+e.getMessage(),e); } } public static Datastore getDB(String dbName){ Datastore datastore=null; if(runInstance.mongoClient!=null&&runInstance.morphia!=null){ datastore = runInstance.morphia.createDatastore(runInstance.mongoClient, dbName); datastore.ensureIndexes(); }else{ Log.logger.warn("mongoDB 未初始化!"); } return datastore; } } 實體類: package com.luo.model; import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; @Entity(value = "user_score", noClassnameStored = true) public class UserDoc { @Id private Object mgId; private String name; private Integer score; public Object getMgId() { return mgId; } public void setMgId(Object mgId) { this.mgId = mgId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } } //需要封裝結果集: package com.luo.model; import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; @Entity public class ScoreGroupDOC { @Id private Object mgId; private Integer totalScore; public Object getMgId() { return mgId; } public void setMgId(Object mgId) { this.mgId = mgId; } public Integer getTotalScore() { return totalScore; } public void setTotalScore(Integer totalScore) { this.totalScore = totalScore; } } package com.luo.model; import org.mongodb.morphia.Datastore; import org.mongodb.morphia.aggregation.AggregationPipeline; import org.mongodb.morphia.query.Query; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Iterator; import static org.mongodb.morphia.aggregation.Group.grouping; import static org.mongodb.morphia.aggregation.Group.id; import static org.mongodb.morphia.aggregation.Group.sum; @Service public class UserService { @Resource SimpleMongoDBDao<UserDoc> simpleMongoDBDao; public ScoreGroupDOC getTotalScore(){ Datastore datastore = simpleMongoDBDao.getDB(); Query<UserDoc> query = datastore.createQuery(UserDoc.class);//查詢對象 /*獲取分數合計*/ AggregationPipeline pipeline = datastore.createAggregation(UserDoc.class) //封裝到結果集的字段 獲取聚合的字段 .match(query).group(id(grouping("mgId")),grouping("totalScore", sum("score"))); Iterator<ScoreGroupDOC> iterator = pipeline.aggregate(ScoreGroupDOC.class); ScoreGroupDOC groupDOC = new ScoreGroupDOC(); while (iterator.hasNext()) { groupDOC = iterator.next(); } return groupDOC; } }
一個剛入行不久的新手程序員也是剛剛接觸mongoDB不到一周的時間,第一次寫。做個記錄,morphia這個框架在網上的資料實在太少了。當時為了求賬單的金額合計查了一整天的資料。東拼西湊最終還是把結果做出來了。不過說實在的速度雖然比mySql要好一些。50多萬條數據在我自己的筆記本上還是需要2秒多的時間。希望有高手指點一下 提升一下我的聚合查詢速度;
不甚感激;
