英文:
How to project the result of an aggregate query result with Panache and MongoDB?
问题
如何将结果投影到自定义类?项目()只存在于find()中。
英文:
Consider this method:
public static Uni<List<ReactivePanacheMongoEntityBase>> getAverage(String productId) {
List<Bson> pipeline = new ArrayList<>();
Bson match = Aggregates.match(Filters.eq("productId", new ObjectId(productId)));
Bson group = Aggregates.group("$productId", new BsonField("Average", new Document("$avg", "$score")));
pipeline.add(match);
pipeline.add(group);
return Rating.mongoCollection().aggregate(pipeline).collect().asList();
}
How to I project the results to a custom class? The project() only exists in conjunction with find() 🤔
答案1
得分: 1
在MongoDB中,您可以使用project
聚合阶段来指定聚合管道返回的文档的形状。要将结果映射到自定义的Java类,您可以结合使用project
阶段和编解码器注册表。
让我们创建一个自定义类来表示结果。假设您希望将结果映射到名为AverageRating
的类中。
public class AverageRating {
private ObjectId productId;
private Double average;
// Getters and setters
}
修改getAverage
方法以包含project
阶段,并将结果映射到AverageRating
类。您可以使用Uni
类的map
方法来实现这一点。
import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import io.smallrye.mutiny.Uni;
import java.util.ArrayList;
import java.util.List;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.computed;
public static Uni<List<AverageRating>> getAverage(String productId) {
List<Bson> pipeline = new ArrayList<>();
Bson match = Aggregates.match(Filters.eq("productId", new ObjectId(productId)));
Bson group = Aggregates.group("$productId", new BsonField("average", new Document("$avg", "$score")));
Bson project = Aggregates.project(fields(computed("productId", "$_id"), computed("average", "$average")));
pipeline.add(match);
pipeline.add(group);
pipeline.add(project);
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
return Rating.mongoCollection()
.withCodecRegistry(pojoCodecRegistry)
.aggregate(pipeline, AverageRating.class)
.collect()
.asList();
}
在上面的示例中,project
阶段指定了聚合管道返回的文档的形状。它还使用编解码器注册表将结果映射到AverageRating
POJO(普通的Java对象)。请注意,aggregate
方法现在使用AverageRating.class
进行参数化,指示结果应映射到的类的类型。
英文:
In MongoDB, you can use the project
aggregation stage to specify the shape of the documents returned by the aggregation pipeline. To map the result to a custom Java class, you can use a combination of the project
stage and the codec registry.
Let's create a custom class to represent the result. Suppose you want to map the result to a class called AverageRating
.
public class AverageRating {
private ObjectId productId;
private Double average;
// Getters and setters
}
Modify the getAverage
method to include the project
stage and to map the results to AverageRating
class. You can use the map
method of the Uni
class for this.
import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import io.smallrye.mutiny.Uni;
import java.util.ArrayList;
import java.util.List;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.computed;
public static Uni<List<AverageRating>> getAverage(String productId) {
List<Bson> pipeline = new ArrayList<>();
Bson match = Aggregates.match(Filters.eq("productId", new ObjectId(productId)));
Bson group = Aggregates.group("$productId", new BsonField("average", new Document("$avg", "$score")));
Bson project = Aggregates.project(fields(computed("productId", "$_id"), computed("average", "$average")));
pipeline.add(match);
pipeline.add(group);
pipeline.add(project);
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
return Rating.mongoCollection()
.withCodecRegistry(pojoCodecRegistry)
.aggregate(pipeline, AverageRating.class)
.collect()
.asList();
}
In the above example, the project
stage specifies the shape of the documents returned by the aggregation pipeline. It is also using the codec registry to map the result to the AverageRating
POJO (Plain Old Java Object). Note that the aggregate
method is now parameterized with AverageRating.class
which indicates the type of class the results should be mapped to.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论