如何在Spring中的Mongodb文档中对Map Key执行求和

时间:2014-10-17 23:16:59

标签: spring mongodb-java

我的MongoDB文档如下所示:

{
"_class" : "com.foo.foo.FooClass",
"_id" : ObjectId("5441948f3004e65fbda72d9c"),
"actionType" : "LOGIN",
"actor" : "bolt",
"extraDataMap" : {
   "workHours" : NumberLong(11869) 
},

}

其中extraDataMap是从java代码存储的HashMap。我必须得到所有文件,其中" actionType"是"登录",分组"演员"并总结所有" workHours"对于那些个人演员

如果我直接在MongoDB上查询,它可以工作:

db.activityLog.aggregate([
{$match : { actionType : "LOGIN" }},
{$group : { "_id" : "$actor",  "hours" : {  "$sum" : "$extraDataMap.workHours" }  } },
{$sort : {_id : 1}}
]);

但是如果我从Java代码运行查询

TypedAggregation<ActivityLog> agg = Aggregation.newAggregation(ActivityLog.class,
            buildCriteria(),
            group("actor").sum("extraDataMap.workHours").as("hours"),
            sort(Sort.Direction.ASC, MongoActivityLogRepository.DOCUMENT_ID_FIELD_NAME)
    );
AggregationResults<ActivityLog> result = mongoOperations.aggregate(agg, ActivityLog.class);
List<ActivityLog> results = result.getMappedResults();

它给出了以下错误:

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property work found for type java.lang.String
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:290)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:274)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:245)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:91)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.getValue(GroupOperation.java:359)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.toDBObject(GroupOperation.java:355)
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDBObject(GroupOperation.java:300)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:228)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1287)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1264)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1253)

真的很感激所有的快速反应:)

1 个答案:

答案 0 :(得分:1)

我遇到了与你相同的问题,我找到了这个解决方案

使用普通聚合,而不是使用TypedAggregation。这样,弹簧数据不会执行类型检查。

如下:

Aggregation agg = Aggregation.newAggregation(
        buildCriteria(),
        group("actor").sum("extraDataMap.workHours").as("hours"),
        sort(Sort.Direction.ASC, MongoActivityLogRepository.DOCUMENT_ID_FIELD_NAME)
);

List<ActivityLog> results = mongoOperations.aggregate(agg, mongoOperations.getCollectionName(ActivityLog.class), ActivityLog.class).getMappedResults();

看到我使用了不同的mongoOperations.aggregate签名,因为我们没有使用TypedAggregation,所以我们必须指出我们正在执行聚合的集合。

我希望这会对你有所帮助。