MongoDB聚合查询示例
目的:
- 统计book_order表的每个用户的order总数(total),以及失效的数量(invalid)
- 查询用户的信息DBRef(java代码中有查询,使用DBRef查询)
mongodb语法示例:
aggregate会一层一层查询
db.book_order.aggregate([
{$match:{ user: { $exists:true } }},
{$project:
{
user:1,
status: 1,
statuses:
{$cond:
{ if:{ $eq: [ "$status", 4 ] }, then: 1, else: 0 }
}
}
},
{$group:{_id:"$user",total:{$sum:1},invalid:{$sum:"$statuses"},statusArray:{$push:"$status"}}},
{$project:{_id:1,total:1,invalid:1,statusArray:1}},
{$sort:{invalid:-1}},
{$skip:0},
{$limit:10}
])
java mongodb示例:
public ReportPage<DBObject> aggregateGroupPage(
DBObject cond, //筛选条件
DBObject initProject, //文档初始结构
DBObject group, //分组处理
DBObject finalProject,//文档最终结构
DBObject sort, //排序
int pageNum, //当前页
int pageSize, //每页数量
String collectionName, //表名
String groupColumnName) {//需要分组的字段名
int count = getGroupSize(collectionName, groupColumnName);//数据总数
List<DBObject> aggregateList = new ArrayList<>();
// 过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
BasicDBObject match = new BasicDBObject("$match", cond);
aggregateList.add(match);
//过滤需要的字段
aggregateList.add(initProject);
// 将集合中的文档分组,统计结果。
aggregateList.add(group);
// 过滤最终结果的字段
aggregateList.add(finalProject);
// 将输入文档排序后输出。Ascending升 Descending
aggregateList.add(sort);
// 在聚合管道中跳过指定数量的文档,并返回余下的文档。
BasicDBObject skip = new BasicDBObject("$skip", (pageNum - 1) * pageSize);
aggregateList.add(skip);
// 限制MongoDB聚合管道返回的文档数。
BasicDBObject limit = new BasicDBObject("$limit", pageSize);
aggregateList.add(limit);
// 获取返回的结果集
AggregationOutput output = mongoTemplate.getCollection(collectionName).aggregate(aggregateList);
Iterable<DBObject> list = output.results();
List<DBObject> rows = new ArrayList<>();
for (DBObject dbObject : list) {//DBRef关联表的查询
String str = dbObject.get("_id").toString();
DBRef dbRef = (DBRef) JSON.parse(str);
ObjectId oid = new ObjectId((String) dbRef.getId());
DBObject userQuery = new BasicDBObject("_id", oid);
DBObject refObj = mongoTemplate.getCollection(dbRef.getCollectionName())
.findOne(userQuery);
/*删除不需要的字段 如带$*/
refObj.removeField("_id");
dbObject.removeField("_id");
refObj.removeField("_class");;
dbObject.put(groupColumnName,refObj);
rows.add(dbObject);
}
//返回结果,包含数据rows、数据总数count、每页数量pageSize、总页数pageCount、当前页pagNum
ReportPage<DBObject> page = new ReportPage(rows, count, pageSize);
page.setTotalCount(count);
page.setPageNum(pageNum);
return page;
}
/**
* 查询某张表数据
*
* @param pageNum
* @param pageSize
*/
public void getCreditReportForm( int pageNum,int pageSize){
// 筛选条件
Query query = Query.query(Criteria.where("user").exists(true));
DBObject cond = query.getQueryObject();
BasicDBObject match = new BasicDBObject("$match", cond);
// 所需文档初始字段
String project = " {" +
" $project:" +
" {" +
" user: 1," +
" status: 1," +
" statuses:" +
" {" +
" $cond: { if: { $eq: [ \"$status\", 5 ] }, then: 1, else: 0 }" +
" }" +
" }" +
" }";
DBObject initProject = (DBObject) JSON.parse(project);
// 将集合中的文档分组,统计结果。
DBObject groupFields = new BasicDBObject("_id", "$user");
groupFields.put("count", new BasicDBObject("$sum", 1));
groupFields.put("invalid", new BasicDBObject("$sum","$statuses"));
groupFields.put("statusArray", new BasicDBObject("$push","$status"));
BasicDBObject group = new BasicDBObject("$group", groupFields);
// 所需文档最终字段
DBObject projectFields = new BasicDBObject("_id", 1)
.append("count",1)
.append("invalid",1);
BasicDBObject finalProject = new BasicDBObject("$project", projectFields);
//排序
BasicDBObject sort = new BasicDBObject("$sort", new BasicDBObject(
"invalid", -1));
//最终结果
ReportPage<DBObject> reportPage= reportDao.aggregateGroupPage(cond,initProject,group,finalProject,sort, pageNum, pageSize,"book_order","user");
}
表结构:
{
"_id" : ObjectId("5acd5b3702d5c7f0bf18b5a6"),
"_class" : "org.zkhz.epos.model.OrderModel",
"updateTime" : ISODate("2018-04-11T00:47:51.015Z"),
"status" : 4,
"orderDate" : ISODate("2018-04-11T16:00:00Z"),
"createTime" : ISODate("2018-04-11T00:47:51.015Z"),
"vmenuName" : "15元菜谱-04",
"user" : {
"$ref" : "sm_user",
"$id" : ObjectId("5ab710a734e9077bf11a158b")
}
}
查询结果示例:
{ "_id" : DBRef("sm_user", ObjectId("5ab710a734e9077bf11a158b")), "total" : 5, "invalid" : 3, "statusArray" : [ 3, 3, 4, 4, 4 ] }
{ "_id" : DBRef("sm_user", ObjectId("5abb45a534e98c96a4018430")), "total" : 1, "invalid" : 0, "statusArray" : [ 1 ] }
DBRef查询结果示例(用户信息):
{ "vUserName" : "管理" , "vUserSex" : "0" , "vUserEmail" : "[email protected]" }