以下是我的文档:
@Document(collection = "products")
@Data
@EqualsAndHashCode
public class Product {
@Id
private String id;
@Field("lang_content_list")
private List<ProductLangContent> contentList;
@Data
public static class ProductLangContent {
@Field("lang")
private String lang;
}
}
我只想获取其中的 contentList lang ='en'。 lang在客栈清单中是唯一的。
注意:我正在使用 Mongotemplate
我的示例json是:
{
"_id" : ObjectId("5d2040f9f7c5ac1e9d8ef712"),
"lang_content_list" : [
{
"lang" : "en"
},
{
"lang" : "np"
}
]
"_class" : "com.sn.application.model.Product"
}
所需的查询结果是:
{
"_id" : ObjectId("5d2040f9f7c5ac1e9d8ef712"),
"lang_content_list" : [
{
"lang" : "en"
}
]
}
我尝试了几次查询,但是没有运气:
Aggregation aggregation = newAggregation(
project().and(filter("contentList")
.as("item")
.by(valueOf(
"item.lang")
.equalToValue(
"en")))
.as("contentList")
);
List<Product> results = mongoTemplate.aggregate(aggregation, Product.class, Product.class).getMappedResults();
输出为: contentList 为空。
尝试:
Criteria elementMatchCriteria = Criteria.where("contentList").elemMatch(Criteria.where("lang").is("en"));
它给出了contentList中的所有元素。我不要我只希望在lan ='en'的内部列表中有一个对象。
非常感谢。
尝试:
AggregationOperation match = Aggregation.match(Criteria.where("contentList.lang").is("en"));
AggregationOperation unwind = Aggregation.unwind("contentList");
AggregationOperation group = Aggregation.group("id")
.push("contentList").as("contentList");
List<AggregationOperation> operations = new ArrayList<>();
operations.add(match);
operations.add(unwind);
operations.add(match);
operations.add(group);
Aggregation aggregation = Aggregation.newAggregation(operations);
List<Product> results = mongoTemplate.aggregate(aggregation, Product.class, Product.class).getMappedResults();
System.out.println(results.get(0).getContentList() != null);
输出为: false 。内部数组对象为null。
答案 0 :(得分:1)
您的文档具有一个数组字段“ contentList”,该字段将具有多个“ lang”。我假设您要过滤/获取“ contentList”中至少一个“ lang”为“ en”的所有文档。然后使用:
Criteria elementMatchCriteria = Criteria.where("contentList.lang").is("en"));
如果只希望在lang ='en'的内部数组中使用该对象,则需要使用聚合管道,例如:
链接:https://mongoplayground.net/p/JaJ7420i4qJ
db.collection.aggregate([
{
$match: {
"lang_content_list.lang": "en"
}
},
{
$unwind: "$lang_content_list"
},
{
$match: {
"lang_content_list.lang": "en"
}
},
{
$group: {
"_id": "$_id",
"_class": {
$first: "$_class"
},
"lang_content_list": {
$push: "$lang_content_list"
}
}
}
])
使用最后一个小组阶段的原因是,在您的对象中,contentList是一个数组,因此我们需要将lang对象包装为数组,否则,如果可以更改返回类型对象,则不需要。
在春季MongoTemplate代码中:
AggregationOperation match = Aggregation.match(Criteria.where("lang_content_list.lang").is("en"));
AggregationOperation unwind = Aggregation.unwind("lang_content_list");
AggregationOperation group = Aggregation.group("_id")
.first("_class").as("_class")
.push("lang_content_list").as("lang_content_list");
List<AggregationOperation> operations = new ArrayList<>();
operations.add(match);
operations.add(unwind);
operations.add(match);
operations.add(group);
Aggregation aggregation = Aggregation.newAggregation(operations);
List<Product> results = mongoTemplate.aggregate(aggregation, Product.class, Product.class).getMappedResults();