Mongodb 使用Mongo模板在Spring Boot中过滤内部Arraylist项的Mongo查询
以下是我的文件:Mongodb 使用Mongo模板在Spring Boot中过滤内部Arraylist项的Mongo查询,mongodb,spring-boot,mongotemplate,Mongodb,Spring Boot,Mongotemplate,以下是我的文件: @Document(collection = "products") @Data @EqualsAndHashCode public class Product { @Id private String id; @Field("lang_content_list") private List<ProductLangContent> contentList; @Data public static class Pr
@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;
}
}
所需的查询结果是:
{
"_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中的所有元素。我不想那样。我只希望在内部列表中有一个对象,其中lan='en'
非常感谢你
尝试:
Criteria elementMatchCriteria = Criteria.where("contentList").elemMatch(Criteria.where("lang").is("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);
AggregationOperation-match=Aggregation.match(Criteria.where(“contentList.lang”).is(“en”);
AggregationOperation unwind=Aggregation.unwind(“内容列表”);
AggregationOperation组=Aggregation.group(“id”)
.推送(“内容列表”)。作为(“内容列表”);
列表操作=新建ArrayList();
操作。添加(匹配);
操作。添加(展开);
操作。添加(匹配);
操作。添加(组);
聚合聚合=聚合。新建聚合(操作);
List results=mongoTemplate.aggregate(聚合,Product.class,Product.class).getMappedResults();
System.out.println(results.get(0.getContentList()!=null);
输出为:false。内部数组对象为空
您的文档有一个数组字段“contentList”,它将有多个“lang”。我假设您想要筛选/获取所有文档,其中“contentList”中至少有一个“lang”是“en”。然后使用:
Criteria elementMatchCriteria = Criteria.where("contentList.lang").is("en"));
如果只希望lang='en'所在的内部数组中的该对象,则需要使用聚合管道,如:
链接:
使用最后一个组阶段的原因是,在您的对象中,contentList是一个数组,因此我们需要将lang对象包装为数组,否则,如果您可以更改返回类型对象,则不需要
在Spring 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();
AggregationOperation match=Aggregation.match(Criteria.where(“lang\u content\u list.lang”)。是(“en”);
AggregationOperation unwind=聚合。unwind(“语言内容列表”);
AggregationOperation组=Aggregation.group(“\u id”)
.第一类(“U类”)。作为(“U类”)
.push(“语言内容列表”).as(“语言内容列表”);
列表操作=新建ArrayList();
操作。添加(匹配);
操作。添加(展开);
操作。添加(匹配);
操作。添加(组);
聚合聚合=聚合。新建聚合(操作);
List results=mongoTemplate.aggregate(聚合,Product.class,Product.class).getMappedResults();
谢谢。但我只想在lang='en'所在的内部数组中使用该对象。有没有办法把它过滤掉?为了更好地理解,我更新了问题。更新的答案仅针对内部数组中的对象,其中lang='en'对不起,打扰一下,您能否更新我正在使用的语法MongoTemplate包的查询:org.springframework.data.mongodb.core.MongoTemplate;嘿,非常感谢。我根据你的建议尝试了一段时间后找到了解决办法。非常感谢。嗨,@Rajat Goel,你能再帮我一次吗。我在以下链接中发布了问题:
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"
}
}
}
])
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();