从mongoDB中的手动参考中查找所有嵌入式文档

我在项目中使用mongodb和spring-boot。我使用手册参考指出了一个集合,我的结构就像下面这样。

{

_id : "reel_id_1",

name: "reel 1",

category :[

{

_id : "category_id_1",

name: "category 1",

videos: ["video_id_1","video_id_2"]

}

]

}

{

_id: "video_id_1", // first document

name: "mongo"

}

{

_id: "video_id_2", // seconddocument

name: "java"

}

Java类是

@Document

@Data

public class Reel {

@Id

private ObjectId _id;

private String name;

List<Category> category;

}

@Data

public class Category {

@Id

private ObjectId _id=new ObjectId();

private String name;

Video videos;

}

@Document

@Data

public class Video {

@Id

private ObjectId _id = new ObjectId();

private String name;

}

我试图通过mongoTemplate加入两个文档

public List<Reel> findById(ObjectId _id) {

LookupOperation lookupOperation = LookupOperation.newLookup()

.from("video")

.localField("category.videos")

.foreignField("_id")

.as("category.videos");

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

Aggregation agg = newAggregation(unwindOperation,match(Criteria.where("_id").is(_id)),lookupOperation);

Aggregation aggregation = newAggregation(lookupOperation);

List<Reel> results = mongoTemplate.aggregate(aggregation, "reel", Reel.class).getMappedResults();

return results;

}

但这会引发错误。

Failed to instantiate java.util.List using constructor NO_CONSTRUCTOR with arguments

但是由于使用“ unwind”,所以创建了一个新的Entity 并添加Category

category而不是List<Category> category。和二手

List<UnwindReel> results = mongoTemplate.aggregate(aggregation, "reel",

UnwindReel.class).getMappedResults();

它仅合并第一个视频(video_id_1)对象。如何获取

所有对象?有什么方法可以提取吗?有人可以让我知道我在这里错过了什么吗?提前致谢。

回答:

您存储在数据库中的JSON结构错误。您的Reel课程需要的列表Category,但在数据库中您已存储为嵌套对象。

您需要在之后添加此阶段 $lookup

{

"$addFields": {

"category": {

"$map": {

"input": "$category.videos",

"in": {

"videos": "$$this"

}

}

}

}

}

Java代码

public List<Reel> findById(String _id) {

Aggregation aggregation = Aggregation.newAggregation(

Aggregation.match(Criteria.where("_id").is(_id)),

Aggregation.lookup(mongoTemplate.getCollectionName(Video.class), "category.videos", "_id", "category.videos"),

new AggregationOperation() {

@Override

public Document toDocument(AggregationOperationContext context) {

return new Document("$addFields",

new Document("category", new Document("$map", new Document("input", "$category.videos")

.append("in", new Document("videos", "$$this")))));

}

})

.withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

LOG.debug(

aggregation.toString().replaceAll("__collection__", mongoTemplate.getCollectionName(Reel.class)));

return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Reel.class), Reel.class)

.getMappedResults();

}

回答:

  1. 不要硬编码集合名称,使用更好的mongoTemplate.getCollectionName方法
  2. 始终在执行之前记录聚合管道,这有助于调试。
  3. 如果您的集合将来会增长,请使用{allowDiskUse: true}MongoDb聚合选项。

以上是 从mongoDB中的手动参考中查找所有嵌入式文档 的全部内容, 来源链接: utcz.com/qa/411870.html

回到顶部