java MongoTemplate 聚合项目嵌套文档
java MongoTemplate aggregate with project nested document
我有一个文件。
{
"errors" : [
{
"priority" : 3,
"category" : "aaa"
"other":"nothing"
},
{
"priority" : 4,
"category" : "bbb"
"other":"nothing"
},
{
"priority" : 2,
"category" : "ccc"
"other":"nothing"
},
{
"priority" : 3,
"category" : "ddd"
"other":"nothing"
},
{
"priority" : 2,
"category" : "eee"
"other":"nothing"
}
],
"file_name" : "xxx.json",
"vehicle_id" : "esdf",
"day" : "2022-03-08"
}
我用js客户端执行命令
db.wty_test.aggregate({
$project: {
'_id': 0, 'errors.priority': 1, 'errors.category': 1, 'file_name': 1, 'vehicle_id': 1,
}
})
我得到了我想要的结果。
错误是一个包含对象的数组。
现在我需要用java客户端(springboot-data-mongo)覆盖这个命令。这是我的 java 代码。
import org.springframework.data.mongodb.core.MongoTemplate;
...
Aggregation aggregation = Aggregation.newAggregation(Aggregation.project("errors.priority", "errors.category", "file_name", "vehicle_id"));
mongoTemplate.aggregate(aggregation, "wty_test", HashMap.class).getMappedResults();
优先级和类别没有错误。
如何使用java得到和js一样的结果?
我试试 nested.But 这不是我想要的。
您想使用 nested()
函数,如下所示:
AggregationOperation project = Aggregation.project("file_name", "vehicle_id").
and("errors").nested(Fields.fields("priority","category"))
Aggregation aggregation = Aggregation.newAggregation(project);
这是获得所需结果的方法。
Document projectn = new Document("$project",
new Document("_id", 0L)
.append("file_name", 1L)
.append("vehicle_id", 1L)
.append("errors",
new Document("$map",
new Document("input", "$errors")
.append("in",
new Document("priority", "$$this.priority")
.append("category", "$$this.category")
)
)
)
);
List<Document> pipeline = Arrays.asList(projectn);
List<Document> results = mongoOps.getCollection("collection_name")
.aggregate(pipeline)
.into(new ArrayList<>());
注意这里使用了MongoDBJavaDriverAPI查询语法,而Document
是org.bson.Document
。将本机查询转换为 Java 驱动程序使用 $map
聚合数组运算符(看起来这就是(可能唯一的)方式)。
使用 MongoTemplate.aggregate
代码是:
Aggregation agg = newAggregation(
project()
.and(
VariableOperators.Map.itemsOf("errors")
.as("e")
.andApply(ctx -> new Document("priority", "$$e.priority").append("category", "$$e.category") ))
.as("errors")
.andExclude("_id")
.andInclude("file_name", "vehicle_id")
);
AggregationResults<Document> results = mongoOps.aggregate(agg, "collection_name", Document.class);
替代方法:
如果您的查询只是关于 投影,您可以使用 MongoTemplate#find
方法使用以下查询。这更容易构建和理解:
db.collection.find(
{}, // your query filter
{ _id: 0, 'errors.category': 1, 'errors.priority': 1, file_name: 1, vehicle_id: 1 }
)
它的 MongoTemplate
版本:
Query query = new Query();
query.fields()
.include("errors.priority", "errors.category", "file_name", "vehicle_id")
.exclude("_id");
List<Document> results = mongoOps.find(query, Document.class, "collection_name");
我有一个文件。
{
"errors" : [
{
"priority" : 3,
"category" : "aaa"
"other":"nothing"
},
{
"priority" : 4,
"category" : "bbb"
"other":"nothing"
},
{
"priority" : 2,
"category" : "ccc"
"other":"nothing"
},
{
"priority" : 3,
"category" : "ddd"
"other":"nothing"
},
{
"priority" : 2,
"category" : "eee"
"other":"nothing"
}
],
"file_name" : "xxx.json",
"vehicle_id" : "esdf",
"day" : "2022-03-08"
}
我用js客户端执行命令
db.wty_test.aggregate({
$project: {
'_id': 0, 'errors.priority': 1, 'errors.category': 1, 'file_name': 1, 'vehicle_id': 1,
}
})
我得到了我想要的结果。
现在我需要用java客户端(springboot-data-mongo)覆盖这个命令。这是我的 java 代码。
import org.springframework.data.mongodb.core.MongoTemplate;
...
Aggregation aggregation = Aggregation.newAggregation(Aggregation.project("errors.priority", "errors.category", "file_name", "vehicle_id"));
mongoTemplate.aggregate(aggregation, "wty_test", HashMap.class).getMappedResults();
如何使用java得到和js一样的结果?
我试试 nested.But 这不是我想要的。
您想使用 nested()
函数,如下所示:
AggregationOperation project = Aggregation.project("file_name", "vehicle_id").
and("errors").nested(Fields.fields("priority","category"))
Aggregation aggregation = Aggregation.newAggregation(project);
这是获得所需结果的方法。
Document projectn = new Document("$project",
new Document("_id", 0L)
.append("file_name", 1L)
.append("vehicle_id", 1L)
.append("errors",
new Document("$map",
new Document("input", "$errors")
.append("in",
new Document("priority", "$$this.priority")
.append("category", "$$this.category")
)
)
)
);
List<Document> pipeline = Arrays.asList(projectn);
List<Document> results = mongoOps.getCollection("collection_name")
.aggregate(pipeline)
.into(new ArrayList<>());
注意这里使用了MongoDBJavaDriverAPI查询语法,而Document
是org.bson.Document
。将本机查询转换为 Java 驱动程序使用 $map
聚合数组运算符(看起来这就是(可能唯一的)方式)。
使用 MongoTemplate.aggregate
代码是:
Aggregation agg = newAggregation(
project()
.and(
VariableOperators.Map.itemsOf("errors")
.as("e")
.andApply(ctx -> new Document("priority", "$$e.priority").append("category", "$$e.category") ))
.as("errors")
.andExclude("_id")
.andInclude("file_name", "vehicle_id")
);
AggregationResults<Document> results = mongoOps.aggregate(agg, "collection_name", Document.class);
替代方法:
如果您的查询只是关于 投影,您可以使用 MongoTemplate#find
方法使用以下查询。这更容易构建和理解:
db.collection.find(
{}, // your query filter
{ _id: 0, 'errors.category': 1, 'errors.priority': 1, file_name: 1, vehicle_id: 1 }
)
它的 MongoTemplate
版本:
Query query = new Query();
query.fields()
.include("errors.priority", "errors.category", "file_name", "vehicle_id")
.exclude("_id");
List<Document> results = mongoOps.find(query, Document.class, "collection_name");