Spring Data + MongoDB 无效引用错误

问题描述 投票:0回答:2

这是我的代码(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);

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

编辑 这是我的文件:

@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
UserSummaryChannel
属性(无论有没有该字段,聚合都不起作用)。

java spring mongodb spring-data
2个回答
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);
        };

其余聚合操作保持不变。没有抛出任何异常。


0
投票

分裂!

您遇到的问题是因为您没有将 allGamesOnChannel 包含在投影步骤内。

您需要将其添加到

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

我遇到了你所描述的同样的问题,这就是我解决它的方法。

© www.soinside.com 2019 - 2024. All rights reserved.