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秒多的时间。希望有高手指点一下 提升一下我的聚合查询速度;
不甚感激;