mongodb - 如何比较两个不常见的馆藏和档案文件
问题描述
我有两个集合,例如 CollectionA 和 CollectionB 都有共同的字段,即主机名
集合 A:
{
"hostname": "vm01",
"id": "1",
"status": "online",
}
集合 B
{
"hostname": "vm01",
"id": "string",
"installedversion": "string",
}
{
"hostname": "vm02",
"id": "string",
"installedversion": "string",
}
我想要实现的是当我收到收集 B 的帖子消息时
我想根据主机名检查集合 B 中是否存在记录并更新所有值。如果不插入新记录(我已经阅读它可以通过使用 upsert 来实现——仍在寻找如何使其工作)
- 我想检查主机名是否存在于集合 A 中,如果不将记录从集合 B 移动到另一个集合,即集合 C(作为存档记录)。即上面的 hostname=vm02 来自集合 B 的记录应该移动到集合 C
我如何使用springboot mongodb anyhelp来实现这一点。我必须保存集合B的代码如下,我想更新它以实现上述期望的结果
public RscInstalltionStatusDTO save(RscInstalltionStatusDTO rscInstalltionStatusDTO) {
log.debug("Request to save RscInstalltionStatus : {}", rscInstalltionStatusDTO);
RscInstalltionStatus rscInstalltionStatus = rscInstalltionStatusMapper.toEntity(rscInstalltionStatusDTO);
rscInstalltionStatus = rscInstalltionStatusRepository.save(rscInstalltionStatus);
return rscInstalltionStatusMapper.toDto(rscInstalltionStatus);
}
更新 1:下面的工作如我所料,但我认为应该有更好的方法来做到这一点。
public RscInstalltionStatusDTO save(RscInstalltionStatusDTO rscInstalltionStatusDTO) {
log.debug("Request to save RscInstalltionStatus : {}", rscInstalltionStatusDTO);
RscInstalltionStatus rscInstalltionStatus = rscInstalltionStatusMapper.toEntity(rscInstalltionStatusDTO);
System.out.print(rscInstalltionStatus.getHostname());
Query query = new Query(Criteria.where("hostname").is(rscInstalltionStatus.getHostname()));
Update update = new Update();
update.set("configdownload",rscInstalltionStatus.getConfigdownload());
update.set("rscpkgdownload",rscInstalltionStatus.getRscpkgdownload());
update.set("configextraction",rscInstalltionStatus.getConfigextraction());
update.set("rscpkgextraction",rscInstalltionStatus.getRscpkgextraction());
update.set("rscstartup",rscInstalltionStatus.getRscstartup());
update.set("installedversion",rscInstalltionStatus.getInstalledversion());
mongoTemplate.upsert(query, update,RscInstalltionStatus.class);
rscInstalltionStatus = rscInstalltionStatusRepository.findByHostname(rscInstalltionStatus.getHostname());
return rscInstalltionStatusMapper.toDto(rscInstalltionStatus);
}
Update2:使用下面的代码,我可以将记录移动到另一个集合
String query = "{$lookup:{ from: \"vmdetails\",let: {rschostname: \"$hostname\"},pipeline:[{$match:{$expr:{$ne :[\"$hostname\",\"$$rschostname\"]}}}],as: \"rscInstall\"}},{$unwind:\"$rscInstall\"},{$project:{\"_id\":0,\"rscInstall\":0}}";
AggregationOperation rscInstalltionStatusTypedAggregation = new CustomProjectAggregationOperation(query);
LookupOperation lookupOperation = LookupOperation.newLookup().from("vmdetails").localField("hostname").foreignField("hostname").as("rscInstall");
UnwindOperation unwindOperation = Aggregation.unwind("$rscInstall");
ProjectionOperation projectionOperation = Aggregation.project("_id","rscInstall").andExclude("_id","rscInstall");
OutOperation outOperation = Aggregation.out("RscInstallArchive");
Aggregation aggregation = Aggregation.newAggregation(rscInstalltionStatusTypedAggregation,unwindOperation,projectionOperation,outOperation);
List<BasicDBObject> results = mongoTemplate.aggregate(aggregation,"rsc_installtion_status",BasicDBObject.class).getMappedResults();
我在这里遇到的这个问题是它返回多条记录
解决方案
找到了解决方案,可能还有其他最好的解决方案,但对我来说这个有效
创建一个类customeAggregationGeneration(在SO答案中找到并扩展以满足我的需求)
public class CustomProjectAggregationOperation implements AggregationOperation {
private String jsonOperation;
public CustomProjectAggregationOperation(String jsonOperation) {
this.jsonOperation = jsonOperation;
}
@Override
public Document toDocument(AggregationOperationContext aggregationOperationContext) {
return aggregationOperationContext.getMappedObject(Document.parse(jsonOperation));
}
}
String lookupquery = "{$lookup :{from:\"vmdetails\",localField:\"hostname\",foreignField:\"hostname\"as:\"rscinstall\"}}";
String matchquery = "{ $match: { \"rscinstall\": { $eq: [] } }}";
String projectquery = "{$project:{\"rscinstall\":0}}";
AggregationOperation lookupOpertaion = new CustomProjectAggregationOperation(lookupquery);
AggregationOperation matchOperation = new CustomProjectAggregationOperation(matchquery);
AggregationOperation projectOperation = new CustomProjectAggregationOperation(projectquery);
Aggregation aggregation = Aggregation.newAggregation(lookupOpertaion, matchOperation, projectOperation);
ArrayList<Document> results1 = (ArrayList<Document>) mongoTemplate.aggregate(aggregation, "rsc_installtion_status", Document.class).getRawResults().get("result");
// System.out.println(results1);
for (Document doc : results1) {
// System.out.print(doc.get("_id").toString());
mongoTemplate.insert(doc, "RscInstallArchive");
delete(doc.get("_id").toString());
推荐阅读
- python-3.x - Tensorflow 对象检测:使用新检测到的图像重新训练模型
- modelica - 如何使用 SMPM 和逆变器修复“模型未全局平衡”
- javascript - VanillaJS vs JQuery - 等待处理程序直到完成两个异步请求
- java - 使用 for 循环用两个 1D 数组填充 2D 数组
- android - 使用 AppCenter,我能否将用户数据添加到未处理的崩溃报告中?
- .net - 在服务模型中重用存储库模型?
- spring - 如何检测@Cacheable 方法输出是否来自缓存?
- php - AES-256-CBC 加密 Node.Js 但无法在 PHP 中解密
- google-apps-script - 用于检查域中是否存在电子邮件的 Google 应用脚本
- php - php artisan route:cache 显示无法为序列化准备路由 [/]。使用闭包