Spring Data + MongoDB无效引用错误

时间:2018-02-19 20:05:49

标签: java spring mongodb spring-data

这是我的代码(Spring数据):

        MatchOperation matchOperation = Aggregation.match(new Criteria("stats.channelId").is(channelId));

        UnwindOperation unwindOperation = Aggregation.unwind("stats");

        GroupOperation groupOperation = Aggregation.group("id", "discordId")
                .push("stats").as("stats");

        AggregationOperation addFields = (AggregationOperationContext aggregationOperationContext) -> {
                DBObject dbObject =
                        new BasicDBObject("allGamesOnChannel",
                                new BasicDBObject("$sum", "$stats.pickupsPlayed"));
                return new BasicDBObject("$addFields", dbObject);
            };

        SortOperation sortOperation = Aggregation.sort(new Sort(Sort.Direction.DESC, "allGamesOnChannel"));
        LimitOperation limitOperation = Aggregation.limit(maxElements);

        ProjectionOperation projectionOperation = Aggregation.project("id", "discordId", "stats");

        Aggregation aggregation = Aggregation.newAggregation(matchOperation,unwindOperation, matchOperation,groupOperation,addFields,
                sortOperation,limitOperation,projectionOperation);

        AggregationResults<UserSummaryChannel> userSummaries = mongoTemplate.aggregate(aggregation, "pickupUser", UserSummaryChannel.class);

我在上面执行时遇到了这个异常:

Caused by: java.lang.IllegalArgumentException: Invalid reference 'allGamesOnChannel'!
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:99) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:80) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.SortOperation.toDBObject(SortOperation.java:73) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDBObject(AggregationOperationRenderer.java:56) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:580) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate$BatchAggregationLoader.prepareAggregationCommand(MongoTemplate.java:2603) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate$BatchAggregationLoader.aggregate(MongoTemplate.java:2585) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1570) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1511) ~[spring-data-mongodb-1.10.10.RELEASE.jar:na]

执行聚合而不分组:

Aggregation aggregation = Aggregation.newAggregation(matchOperation,addFields,
            sortOperation,limitOperation,projectionOperation);

没有错误,所以我认为分组存在一些问题。我在这里做错了什么想法?我想要做的是过滤嵌入元素的列表,计算这些元素的属性之一的总和并基于它进行排序。也许有类似的方法吗?

EDIT 所以这是我的文件:

@Document
public class PickupUser {
    @Id
    private String id;
    private String discordId;
    private List<UserModeStats> stats;
    private String name;
}

嵌入对象:

@Data
@EqualsAndHashCode(exclude = {"pickupsPlayed", "caps"})
public class UserModeStats {
    public UserModeStats() {}

    private String mode;
    private String channelId;
    private Long pickupsPlayed;
    private Long caps;
}

我想创建的输出文档:

@Data
public class UserSummaryChannel {
    public UserSummaryChannel() {}

    private String id;
    private String discordId;
    private List<UserModeStats> stats;
    //private Long allGamesOnChannel;
}

我不想包含allGamesOnChannel的{​​{1}}属性(聚合在有或没有该字段的情况下不起作用)。

1 个答案:

答案 0 :(得分:0)

这不是一个真正的解决方案,但找到了实现我的目标的另一种方式。我自己“实施”排序操作,以便这样做:

SortOperation sortOperation = Aggregation.sort(new Sort(Sort.Direction.DESC, "allGamesOnChannel"));

现在我有了这个:

AggregationOperation sortOperation2 = (AggregationOperationContext aggregationOperationContext) -> {
            DBObject dbObject =
                    new BasicDBObject("allGamesOnChannel", 1);
            return new BasicDBObject("$sort", dbObject);
        };

Rest聚合操作保持不变。没有例外被抛出。