【发布时间】:2020-03-04 20:45:16
【问题描述】:
我在在 Mongo Shell 中工作的投影上实现过滤器时遇到问题。我有一个 Census 对象,其中包含员工列表。
{
"_id": "ID",
"name": "census1",
"employees": [ {
"eeId": "EE_ID1"
},
{
"eeId": "EE_ID2"
},
{
"eeId": "EE_ID3"
}
}
实际上,这可能包含很多员工。所以我希望能够检索主要的 Census 对象和一部分员工。我已经实现了“切片”,所以这将通过他们的 eeId 检索一组员工。
这很好用:
db.census.aggregate(
[
{
$match: {
"_id": ObjectId("ID1")
}
},
{
$project: {
"censusName": 1,
"employees" : {
$filter : {
input: "$employees",
as: "employees",
cond: { $in: [ "$$employees.eeId", ["EE_ID1", "EE_ID3"]] }
}
}
}
}
]
).toArray()
问题是,我无法用 Java 实现它。这里的 'employeeIds' 是我想要的 ID 字符串。
MatchOperation matchCensusIdStage = Aggregation.match(new Criteria("id").is(censusId));
ProjectionOperation projectStage = Aggregation.project("censusName")
.and(Filter.filter("employees")
.as("employees")
.by(In.arrayOf(employeeIds).containsValue("employees.eeId")))
.as("employees");
Aggregation aggregation = Aggregation.newAggregation(matchCensusIdStage, projectStage);
return mongoTemplate.aggregate(aggregation, Census.class, Census.class).getMappedResults().get(0);
为此,不返回任何结果。我也试过用 BasicDBObject 实现它,但也卡在那里。
编辑(解决方法): 我确实得到了一个使用聚合的解决方案,但没有使用项目上的过滤器。这就是我所做的:
db.parCensus.aggregate(
// Pipeline
[
{
$match: {
"_id": ObjectId("ID1")
}
},
{
$project: {
"_id": 0, "employee": "$employees"
}
},
{
$unwind: "$employee"
},
{
$match: {
"employee.eeId": { $in: ["EE_ID1", "EE_ID3"] }
}
}
]
).toArray()
Java 代码:
MatchOperation matchCensusIdStage = Aggregation.match(new Criteria("id").is(censusId));
ProjectionOperation projectStage = Aggregation.project("censusName").and("employees").as("employee");
UnwindOperation unwindStage = Aggregation.unwind("employee");
MatchOperation matchEmployeeIdsStage = Aggregation.match(new Criteria("employee.eeId").in(employeeIds));
Aggregation aggregation = Aggregation.newAggregation(matchCensusIdStage, projectStage, unwindStage, matchEmployeeIdsStage);
我知道我可以在最后添加一个 $group 以将其放回一个 Census 对象,但我只是创建了一个单独的 CensusEmployee 对象来存储它。
【问题讨论】:
标签: java spring mongodb aggregation-framework