酉卒之子

导航

Mongo对象子集合聚合统计,和对应Java实现

统计子集合里面的字段,数据格式如下(表名是DebutResult):

{
    "_id" : ObjectId("5fa59607b754a52813412722"),
    "taskId" : "5fa58f60b754a569b083d8ac",
    "imsi" : "460110730176756",
    "regional" : "四川省自贡市",
    "firstPlaceId" : "5c505e17498e4a19f0007cbd",
    "firstPlaceName" : "星维电影院",
    "firstCatchTime" : NumberLong(1603411840),
    "catchPointList" : [ 
        {
            "placeId" : "5c505e17498e4a19f0007cbd",
            "catchTime" : NumberLong(1603411840)
        }, 
        {
            "placeId" : "5c74bb5d498ef85d41240622",
            "catchTime" : NumberLong(1603412001)
        }, 
        {
            "placeId" : "5c505e17498e4a19f0007cb9",
            "catchTime" : NumberLong(1603411949)
        }
    ],
    "cdt" : ISODate("2020-11-07T02:29:27.929+08:00")
}

现在要统计指定taskId下面,所有的抓取场所(catchPointList.placeId)和 对应抓取的次数

最后的mongo语句如下:

db.debutResult.aggregate([

{$match: {"taskId": "5fa9f528b754a53776db15ef"}},

{$project: {"_id": 0, "catchPointList": 1}},

{$unwind: "$catchPointList"},

{$group: {_id: "$catchPointList.placeId", countResult: {$sum: 1}}},

{$project: { "_id": 0, "countResult" : 1, "placeId" : "$_id" }}

])

最终的结果是这样的:

 

 

 下面简单解释一下每条的大概意思:

db.debutResult.aggregate([

//过滤条件 {$match: {"taskId": "5fa9f528b754a53776db15ef"}},
//字段转换,保留有用到的字段 {$project: {"_id": 0, "catchPointList": 1}},
//对子集合的处理 {$unwind: "$catchPointList"},
//类似groupBy,分组统计 {$group: {_id: "$catchPointList.placeId", countResult: {$sum: 1}}},
//最后对输出字段再转换一次,方便Java代码对象接收 {$project: { "_id": 0, "countResult" : 1, "placeId" : "$_id" }}
])

其中,$unwind处理后,输出的数据是这样的:

 

 

 

下面介绍一下Java里面代码是什么样的:

  @Override
    public List<PlaceCountBO> getCatchPointByTaskId(String taskId) {

        Criteria where = Criteria.where("taskId").is(taskId);
        MatchOperation match = Aggregation.match(where);

        //可以省略
        ProjectionOperation project = Aggregation.project("catchPointList");

        UnwindOperation unwind = Aggregation.unwind("catchPointList");

        GroupOperation group = Aggregation.group("catchPointList.placeId").count().as("countResult");

        ProjectionOperation project2 = Aggregation.project("countResult").and("_id").as("placeId");

        Aggregation agg = Aggregation.newAggregation(match, project, unwind, group, project2);

        //log.info("DebutFollowResult统计agg = {}", agg.toString());
        AggregationResults<PlaceCountBO> results = mongoTemplate.aggregate(agg, DebutResult.class, PlaceCountBO.class);
        List<PlaceCountBO> countBOList = results.getMappedResults();

        return countBOList;
    }

其中,PlaceCountBO对象里面,只要包含"countResult"和“placeId”字段就行了,可以接收聚合返回的结果

最后,Java环境是spring boot的,引入有关的包就可以了

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

 

posted on 2020-11-11 15:27  酉卒之子  阅读(539)  评论(0编辑  收藏  举报