背景:
我维护两个收藏:
Package
和Module
。在 Module
集合中,每个文档都包含一个名为 packageId
的字段,它对应于 _id
集合中文档的 Package
字段。
来自Package集合的示例文档
"_id": "660dc62edb464b62c8e34b3b",
"workspaceId": "6606a50d59b56908f026a3ab",
"packageUUID": "6605b2ee536675159c565857",
"originPackageId": "6606a51359b56908f026a3b2",
"version": "0.0.7",
"latest": true
}
来自模块集合的示例文档
"_id": "660dc62edb464b62c8e34b3c",
"packageUUID": "6605b2ee536675159c565857",
"packageId": "660dc62edb464b62c8e34b3b",
"version": "0.0.7",
"type": "QUERY_MODULE",
"moduleUUID": "6605b324536675159c565869",
"originModuleId": "6606a51359b56908f026a3bc"
}
我的用例:
当提供模块 ID 列表(即
_ids
集合中的 Module
)时,我的目标是统计满足以下条件的包的数量:
要么
originPackageId
字段不存在。
或者将 latest
字段设置为 true
。
我的尝试:
这是我尝试过的,但它总是返回
0
public long countPackages(List<String> moduleIds) {
AggregationOperation matchModuleIds =
Aggregation.match(Criteria.where(Module.Fields.id).in(moduleIds));
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("package")
.localField("packageId")
.foreignField("_id")
.as("packages");
AggregationOperation unwindPackages = Aggregation.unwind("$packages"); // tried without `$` as well
AggregationOperation matchConditions = Aggregation.match(new Criteria()
.orOperator(
Criteria.where("packages.originPackageId").exists(false),
Criteria.where("packages.latest").is(true)));
AggregationOperation groupByNull = Aggregation.group().count().as("total");
Aggregation aggregation = Aggregation.newAggregation(
matchModuleIds, lookupOperation, unwindPackages, matchConditions, groupByNull);
List<Document> results = mongoTemplate
.aggregate(aggregation, Module.class, Document.class)
.getMappedResults();
if (!results.isEmpty()) {
Document resultDoc = results.get(0);
return resultDoc.get("total", Long.class);
} else {
return 0L;
}
}
我感谢您在这方面的帮助。
从您的代码看来 _id 被视为 ObjectId()。
匹配查询正在执行类似的操作(额外的“$oid”检查)
[{“$match”:{“_id”:{“$in”:[{“$oid”: "660dc62edb464b62c8e34b3c"}]}}}, { "$lookup" : { "from" : "包", “localField”:“packageId”,“foreignField”:“_id”,“as”: “包”}},{“$unwind”:“$packages”},{“$match”:{“$or”:[{ "packages.originPackageId" : { "$exists" : false}}, { "packages.latest" : true}]}}, { "$group" : { "_id" : null, "total" : { “$sum”:1}}}]
但是根据提供的文档,我可以看到“_id”是字符串。因此,在“Module”模型类中将 _id 声明为字符串会执行如下查询,该查询返回正确的结果
[{“$match”:{“_id”:{“$in”:[“660dc62edb464b62c8e34b3c”]}}},{ "$lookup" : { "from" : "包", "localField" : "packageId", "foreignField" : "_id", "as" : "packages"}}, { "$unwind" : "$packages"}, { "$match" : { "$or" : [{ "packages.originPackageId" : { "$exists" : false}}, { "packages.latest" : true}]}}, { "$group" : { “_id”:空,“总计”:{“$sum”:1}}}]
示例模块类:
@Id
@Field(targetType = FieldType.STRING)
private String _id;
private String packageUUID;
private String packageId;
private String version;
private String type;
private String moduleUUID;
private String originModuleId;