Mongo 查询以使用 Mongo 模板过滤 Spring 引导中的内部 Arraylist 项
Mongo query to filter inner Arraylist items in Spring Boot using Mongo Template
以下是我的文档:
@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;
}
}
I want to get only those contentList where
lang = 'en'. lang is unique within innner list.
Note: I am using 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();
output is: contentList is null.
尝试过:
Criteria elementMatchCriteria = Criteria.where("contentList").elemMatch(Criteria.where("lang").is("en"));
It gives all elements in contentList. I don't want that. I want only one object in inner list where 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);
output is: false. Inner array object is coming as null.
您的文档有一个数组字段 "contentList",它将有多个 "lang"。我假设您想要 filter/get 所有那些 "contentList" 中至少有一个 "lang" 是 "en" 的文档。然后使用:
Criteria elementMatchCriteria = Criteria.where("contentList.lang").is("en"));
如果您只想要 lang='en' 的内部数组中的那个对象,您需要使用聚合管道,如:
Link: 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对象包装成数组,否则如果你可以改变return类型对象就不需要。
在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();
以下是我的文档:
@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;
}
}
I want to get only those contentList where lang = 'en'. lang is unique within innner list.
Note: I am using 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();
output is: contentList is null.
尝试过:
Criteria elementMatchCriteria = Criteria.where("contentList").elemMatch(Criteria.where("lang").is("en"));
It gives all elements in contentList. I don't want that. I want only one object in inner list where 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);
output is: false. Inner array object is coming as null.
您的文档有一个数组字段 "contentList",它将有多个 "lang"。我假设您想要 filter/get 所有那些 "contentList" 中至少有一个 "lang" 是 "en" 的文档。然后使用:
Criteria elementMatchCriteria = Criteria.where("contentList.lang").is("en"));
如果您只想要 lang='en' 的内部数组中的那个对象,您需要使用聚合管道,如:
Link: 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对象包装成数组,否则如果你可以改变return类型对象就不需要。
在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();