Spring数据MongoDB-与其他集合的聚合
我正在开发SpringBootV.2.1.3.RELEASE和SpringDataMongoDB。由于关键需求,我必须像下面这样建模,假设员工知道多种技术,但主要语言是任何人 因此,我决定将技术集合分开,并在员工集合中以某种方式关联员工和技术Spring数据MongoDB-与其他集合的聚合,spring,spring-data-mongodb,Spring,Spring Data Mongodb,我正在开发SpringBootV.2.1.3.RELEASE和SpringDataMongoDB。由于关键需求,我必须像下面这样建模,假设员工知道多种技术,但主要语言是任何人 因此,我决定将技术集合分开,并在员工集合中以某种方式关联员工和技术 { "_id" : ObjectId("5ec65750fdcd4e960f4b2f24"), "technologyCd" : "AB", "
{
"_id" : ObjectId("5ec65750fdcd4e960f4b2f24"),
"technologyCd" : "AB",
"technologyName" : "My ABC",
"ltechnologyNativeName" : "XY",
"status" : "A"
}
Criteria criteria = new Criteria();
criteria.andOperator(
StringUtils.isNotBlank(firstName) ? Criteria.where("firstName").is(firstName.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(lastName) ? Criteria.where("lastName").is(lastName.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(email) ? Criteria.where("email").is(email.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(technologyCd) ? Criteria.where("employeeTechnologyRefs.technologyCd").is(technologyCd.toUpperCase())
: Criteria.where(""));
MatchOperation matchStage = Aggregation.match(criteria);
/*GroupOperation groupOp = Aggregation
.group("firstName", "lastName", "email","_id")
.addToSet("employeeTechnologyRefs").as("employeeTechnologyRefs");
*/
LookupOperation lookupOperation = LookupOperation.newLookup().
from("technology_collection_name").
localField("employeeTechnologyRefs.technologyCd").
foreignField("technologyCd").
as("employeeTechnologyRefsOtherName");
/* ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs");
*/
// And if you want to project specific field from employee array you can use something like.
ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs.fieldName")
Aggregation aggregation = Aggregation.newAggregation(matchStage, lookupOperation, projectStage);
AggregationResults<CustomObject> results = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Employee.class), CustomObject.class);
System.out.println(results);
所以,我做了如下的联想-
注:一名员工可以使用多种技术
一名员工可以与多种技术相关联
员工只能拥有一项基本技术
我使用了下面的查询,如何查询技术文档以获得结果并映射它并创建最终对象
Criteria criteria = new Criteria();
criteria.andOperator(
StringUtils.isNotBlank(firstName) ? Criteria.where("firstName").is(firstName.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(lastName) ? Criteria.where("lastName").is(lastName.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(email) ? Criteria.where("email").is(email.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(technologyCd) ? Criteria.where("employeeTechnologyRefs.technologyCd").is(technologyCd.toUpperCase())
: Criteria.where(""));
MatchOperation matchStage = Aggregation.match(criteria);
GroupOperation groupOp = Aggregation
.group("firstName", "lastName", "email","_id")
.addToSet("employeeTechnologyRefs").as("employeeTechnologyRefs");
ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs");
Aggregation aggregation = Aggregation.newAggregation(matchStage, groupOp, projectStage);
AggregationResults<CustomObject> results = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Employee.class), CustomObject.class);
System.out.println(results);
如果您在代码中使用下面的查找操作,您应该能够按照预期得到答案,并且不需要在代码中使用组操作 编辑回答:这就是整个代码的样子。还有一件事,您不需要投影,如果需要,请尝试仅投影特定字段,并且作为查找操作的一部分,不要使用与集合中相同的字段,否则它将覆盖employee集合中的现有数据
{
"_id" : ObjectId("5ec65750fdcd4e960f4b2f24"),
"technologyCd" : "AB",
"technologyName" : "My ABC",
"ltechnologyNativeName" : "XY",
"status" : "A"
}
Criteria criteria = new Criteria();
criteria.andOperator(
StringUtils.isNotBlank(firstName) ? Criteria.where("firstName").is(firstName.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(lastName) ? Criteria.where("lastName").is(lastName.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(email) ? Criteria.where("email").is(email.toUpperCase())
: Criteria.where(""),
StringUtils.isNotBlank(technologyCd) ? Criteria.where("employeeTechnologyRefs.technologyCd").is(technologyCd.toUpperCase())
: Criteria.where(""));
MatchOperation matchStage = Aggregation.match(criteria);
/*GroupOperation groupOp = Aggregation
.group("firstName", "lastName", "email","_id")
.addToSet("employeeTechnologyRefs").as("employeeTechnologyRefs");
*/
LookupOperation lookupOperation = LookupOperation.newLookup().
from("technology_collection_name").
localField("employeeTechnologyRefs.technologyCd").
foreignField("technologyCd").
as("employeeTechnologyRefsOtherName");
/* ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs");
*/
// And if you want to project specific field from employee array you can use something like.
ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs.fieldName")
Aggregation aggregation = Aggregation.newAggregation(matchStage, lookupOperation, projectStage);
AggregationResults<CustomObject> results = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Employee.class), CustomObject.class);
System.out.println(results);
标准=新标准();
条件.与运算符(
StringUtils.isNotBlank(firstName)?条件。其中(“firstName”).is(firstName.toUpperCase())
:标准。其中(“”),
StringUtils.isNotBlank(lastName)?条件。其中(“lastName”).is(lastName.toUpperCase())
:标准。其中(“”),
StringUtils.isNotBlank(email)?条件。其中(“email”)是(email.toUpperCase())
:标准。其中(“”),
StringUtils.isNotBlank(technologyCd)?标准。其中(“employeeTechnologyRefs.technologyCd”)是(technologyCd.toUpperCase())
:标准。其中(“”);
MatchOperation matchStage=聚合。匹配(标准);
/*GroupOperation-groupOp=聚合
.group(“名字”、“姓氏”、“电子邮件”、“身份证”)
.addToSet(“员工技术参考”)。作为(“员工技术参考”);
*/
LookupOperation LookupOperation=LookupOperation.newLookup()。
来自(“技术、集合、名称”)。
localField(“employeeTechnologyRefs.technologyCd”)。
外域(“technologyCd”)。
as(“员工技术名称”);
/*ProjectionOperationProjectStage=Aggregation.project(“employeeTechnologyRefs”);
*/
//如果您想从employee数组中投影特定字段,您可以使用以下命令。
ProjectionOperationProjectStage=Aggregation.project(“employeeTechnologyRefs.fieldName”)
聚合聚合=聚合.newAggregation(matchStage、lookupOperation、projectStage);
AggregationResults=mongoTemplate.aggregate(聚合,mongoTemplate.getCollectionName(Employee.class),CustomObject.class);
系统输出打印项次(结果);
您希望最终结果是什么样的?如果你想加入结果,你可以使用$lookup stage匹配other collection@DeepakSingh中的数据-我已经更新了结果,你能帮我修改查询吗?员工和技术集合是如何链接的?在哪一处?你能分享一下吗?我想你可以在这里使用查找阶段。它们应该链接到“technologyCd”上,因为在技术收藏中,它是一个独特的领域,将尝试。。。它是否返回technologyCd匹配的所有操作?此时此刻,我正在努力映射CustomObject
,您能否演示如何将其与下面所示的聚合一起使用?您能否分享准确的数据(即,您的员工集合和技术集合是什么样子的)。嘿,我已经在上面分享过了,第一个json文档是技术文档,另一个json文档是员工文档。您还需要什么?更新了答案,应该是这样的,请检查您的CustomObject是否与结果结构匹配。