使用Spring Mongodb Aggregation apis转换查询

时间:2016-12-27 12:34:02

标签: spring mongodb mongodb-query aggregation-framework

db.flm_conversation.aggregate(
[
    {$match: {"conversationRecords.isPrimary":true,"conversationRecords.commentTime":{'$gte': new Date('2016-12-18 00:00:00'), '$lte': new Date('2016-12-18 23:59:59')} } },
    {$unwind:"$conversationRecords"},
    { $group: {
        _id: {
            "commentLevel": "$commentLevel",
            "time":{"$add": [
                { 
                    "$subtract": [
                        { "$subtract": [
                            "$conversationRecords.commentTime",
                            new Date(0) 
                        ]}
                        ,
                        { "$mod": [
                            { "$subtract": [
                               "$conversationRecords.commentTime", 
                                new Date(0)
                            ]},
                            1000 * 60 * 30
                        ]}
                    ]
                },
                new Date(0)
            ]}
        },
        count: { "$sum": 1 }
    }},
    { $group: {_id: "$_id.commentLevel",count: { "$sum": 1 },pointrecord:{$push: {time:"$_id.time",count:"$count"} } }},
    { $project: { _id: 1,count:1,pointrecord:1 } }
])

如何使用Spring Mongodb Aggregation apis转换此查询?

AggregationOperation match = Aggregation.match(Criteria.where("conversationRecords.isPrimary").is(true)
        .and("conversationRecords.commentTime").gte(DateUtils.stringToDate("2016-12-18 00:00:00","yyyy-MM-dd HH:mm:ss")).lte(DateUtils.stringToDate("2016-12-18 23:59:59","yyyy-MM-dd HH:mm:ss")));
AggregationOperation unwind = Aggregation.unwind("conversationRecords");
AggregationOperation group = Aggregation.group("commentLevel");
Aggregation agg = newAggregation(match,unwind,group);
AggregationResults<SummaryRecordAggre>  groupResults
        = mongoTemplate.aggregate(agg, COLLECTION_NAME, SummaryRecordAggre.class);

我不知道组“$ add”如何转换?我找到了 http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.aggregation

1 个答案:

答案 0 :(得分:0)

你可以尝试这样的事情。我删除了我认为不需要的额外操作员,但如果需要,我们可以轻松地将它们放回去。

第一个组是您需要使用MongoDB对象构建的,因为当前所有聚合运算符都不支持在spring mongo中开箱即用。

第二组推送操作符的方式类似,因为您无法推送多个值。

AggregationOperation match = Aggregation.match(Criteria.where("conversationRecords.isPrimary").is(true)
        .and("conversationRecords.commentTime").gte(DateUtils.stringToDate("2016-12-18 00:00:00", "yyyy-MM-dd HH:mm:ss")).lte(DateUtils.stringToDate("2016-12-18 23:59:59", "yyyy-MM-dd HH:mm:ss")));
AggregationOperation unwind = Aggregation.unwind("conversationRecords");
AggregationOperation firstGroup = context -> context.getMappedObject(new BasicDBObject(
        "$group", new BasicDBObject(
        "_id", new BasicDBObject("commentLevel", "$commentLevel")
        .append(
                "time", new BasicDBObject(
                        "$subtract", new Object[]{"$conversationRecords.commentTime", new BasicDBObject(
                        "$mod", new Object[]{"$conversationRecords.commentTime", 1000 * 60 * 30})}))).append("count", new BasicDBObject("$sum", 1))));
AggregationOperation secondGroup = Aggregation.group("_id.commentLevel").count().as("count").push(new BasicDBObject("time", "$_id.time").append("count", "$count")).as("pointrecord");
AggregationOperation project = Aggregation.project("_id", "count", "pointrecord");
Aggregation agg = newAggregation(match, unwind, firstGroup, secondGroup, project);

这相当于以下查询

[{
    "$match": {
        "conversationRecords.isPrimary": true,
        "conversationRecords.commentTime": {
            "$gte": {
                "$date": "2016-12-27T14:46:50.896Z"
            },
            "$lte": {
                "$date": "2016-12-27T14:46:50.896Z"
            }
        }
    }
}, {
    "$unwind": "$conversationRecords"
}, {
    "$group": {
        "_id": {
            "commentLevel": "$commentLevel",
            "time": {
                "$subtract": ["$conversationRecords.commentTime", {
                    "$mod": ["$conversationRecords.commentTime", 1800000]
                }]
            }
        },
        "count": {
            "$sum": 1
        }
    }
}, {
    "$group": {
        "_id": "$_id.commentLevel",
        "count": {
            "$sum": 1
        },
        "pointrecord": {
            "$push": {
                "time": "$_id.time",
                "count": "$count"
            }
        }
    }
}, {
    "$project": {
        "_id": 1,
        "count": 1,
        "pointrecord": 1
    }
}]
}