使用morphia实现对mongodb的复杂group查询

来源:互联网 发布:中易广告联盟v9源码 编辑:程序博客网 时间:2024/06/08 09:55

morphia是谷歌的一个针对mongodb的数据化持久框架,现在貌似已经迁移到mongodb中
morphia induction
morphia api for java
关于mongodb的介绍不在这里展示,直接进入主题:采用morphia实现对mongodb的复杂group统计
需求:有一个用户集合User,如下:
{
“_id” : ObjectId(“55bf10419d03fb1a88f990ba”),
“userName” : “user6”,
“password” : “123”,
“grade” : 98,
“classId” : 1,
“createTime” : ISODate(“2015-08-12T06:59:57.318Z”)
},
{
“_id” : ObjectId(“55d697fe3a6aae9affb43744”),
“userName” : “user”,
“password” : “123”,
“grade” : 30,
“classId” : 2,
“createTime” : ISODate(“2015-08-13T06:59:57.318Z”)
},
{
“_id” : ObjectId(“55ee48851db2fd2a72b1031f”),
“userName” : “user6”,
“password” : “123”,
“grade” : 43,
“classId” : 2,
“createTime” : ISODate(“2015-08-14T06:59:57.318Z”)
},
{
“_id” : ObjectId(“55ee517b1db2fd2a72b10320”),
“userName” : “user6”,
“password” : “124”,
“grade” : 24,
“classId” : 1,
“createTime” : ISODate(“2015-08-19T06:59:57.318Z”)
}
总共四条记录,现在的需求是:按userName和classId进行分组统计数量和总的grade,且成绩需要大于0,sql如下:
select userName,classId,count(*) as count,sum(case when grade> 0 then grade else 0 end) as totalGrade from Users where grade > 0 group by userName,classId order by userName
查看morphia的API如下图morphia API
可以知道用aggregation就好。
话不多说,上代码
MorphiaAggregation .java如下

package com.marstor.dms.base;import static org.mongodb.morphia.aggregation.Group.first;import static org.mongodb.morphia.aggregation.Group.grouping;import static org.mongodb.morphia.aggregation.Group.id;import static org.mongodb.morphia.aggregation.Group.sum;import java.util.Iterator;import org.mongodb.morphia.Datastore;import org.mongodb.morphia.aggregation.Accumulator;import org.mongodb.morphia.aggregation.AggregationPipeline;import org.mongodb.morphia.aggregation.Sort;import org.mongodb.morphia.logging.Logger;import org.mongodb.morphia.logging.MorphiaLoggerFactory;import org.mongodb.morphia.query.Query;import com.marstor.dms.mongo.util.service.Users;import com.marstor.dms.mongo.util.service.UsersGroup;public class MorphiaAggregation {    private final static Logger LOG = MorphiaLoggerFactory.get(MorphiaAggregation.class);    public static void main(String[] args) {        sumWithGroup();    }    private static void sumWithGroup() {        Datastore ds = DbUtils_Mongo.getMongoDbConnection();        Query<Object> query = ds.getQueryFactory().createQuery(ds);        AggregationPipeline pipeline = ds.createAggregation(Users.class)                 .match(query.filter("grade >", 0))                 .group(                         id(grouping("userName"), grouping("classId")),                         grouping("abc",first("userName")),                         grouping("classId",first("classId")),                         grouping("countAll",new Accumulator("$sum", 1)),                         grouping("totalGrade", sum("grade"))                         )                 .sort(Sort.ascending("abc"));        Iterator<UsersGroup> iterator = pipeline.aggregate(UsersGroup.class);        System.out.println(iterator.hasNext());         while (iterator.hasNext()) {             UsersGroup ug = iterator.next();             System.out.println(ug);         }    }}

User.java如下:

package com.marstor.dms.mongo.util.service;import java.sql.Timestamp;import org.apache.commons.lang.builder.ReflectionToStringBuilder;import org.apache.commons.lang.builder.ToStringStyle;import org.bson.types.ObjectId;import org.mongodb.morphia.annotations.Entity;import org.mongodb.morphia.annotations.Id;import org.mongodb.morphia.annotations.NotSaved;import org.mongodb.morphia.annotations.Property;@Entity(value="Users",noClassnameStored=true)public class Users {    @Id    private ObjectId id;    private String userName;    private String password;    private int grade;    private int classId;    private Timestamp createTime;    public Timestamp getCreateTime() {        return createTime;    }    public void setCreateTime(Timestamp createTime) {        this.createTime = createTime;    }    public int getClassId() {        return classId;    }    public void setClassId(int classId) {        this.classId = classId;    }    public Users() {        super();    }    public ObjectId getId() {        return id;    }    public void setId(ObjectId id) {        this.id = id;    }    public int getGrade() {        return grade;    }    public void setGrade(int grade) {        this.grade = grade;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String toString() {        return ReflectionToStringBuilder.toString( this ,ToStringStyle.MULTI_LINE_STYLE);//      return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE).append("xml", xml).toString();       }}

需要封装的结果集UserGroup.java如下

package com.marstor.dms.mongo.util.service;import org.apache.commons.lang.builder.ReflectionToStringBuilder;import org.apache.commons.lang.builder.ToStringStyle;import org.bson.types.ObjectId;import org.mongodb.morphia.annotations.AlsoLoad;import org.mongodb.morphia.annotations.Embedded;import org.mongodb.morphia.annotations.Entity;import org.mongodb.morphia.annotations.Id;import org.mongodb.morphia.annotations.NotSaved;import org.mongodb.morphia.annotations.Property;@Entitypublic class UsersGroup {    //必不可少    @Id    private String userName;    @Property("classId")    private String classId;    private int totalGrade;     private int countAll;     private String abc;    public String getAbc() {        return abc;    }    public void setAbc(String abc) {        this.abc = abc;    }    public int getCountAll() {        return countAll;    }    public void setCountAll(int countAll) {        this.countAll = countAll;    }    public String getClassId() {        return classId;    }    public void setClassId(String classId) {        this.classId = classId;    }    public UsersGroup() {        super();    }    public int getTotalGrade() {        return totalGrade;    }    public void setTotalGrade(int totalGrade) {        this.totalGrade = totalGrade;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String toString() {        return ReflectionToStringBuilder.toString( this ,ToStringStyle.MULTI_LINE_STYLE);//      return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE).append("xml", xml).toString();       }}

运行MorphiaAggregation.java之后的结果如下:

com.marstor.dms.mongo.util.service.UsersGroup@30dfe0c6[  userName={ "userName" : "user" , "classId" : 2}  classId=2  totalGrade=30  countAll=1  abc=user]com.marstor.dms.mongo.util.service.UsersGroup@3a1e003b[  userName={ "userName" : "user6" , "classId" : 2}  classId=2  totalGrade=43  countAll=1  abc=user6]com.marstor.dms.mongo.util.service.UsersGroup@7a13f4c[  userName={ "userName" : "user6" , "classId" : 1}  classId=1  totalGrade=122  countAll=2  abc=user6]

写出来了就这么点,感觉很容易,但是花了一周的时间了。。。关键是morphia的帮助文档太少了。。。
参考资料:
ZipCodeDataSetTest.java
AggregationTest.java

0 0