MongoDB聚合查询示例

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]"  }

猜你喜欢

转载自blog.csdn.net/jq_motee/article/details/79896720