问题描述
title: string,year: integer,published: boolean,deleted: boolean
属性{ title,year }
构成唯一键,并且该键存在于给定的集合中。即不允许用户在同一年创建具有相同标题的文档。
deleted
扮演以下角色:当用户请求删除文档时,实际上并没有删除该文档,而只是将其标记为已删除。这对于收集创建的文档数量(每个用户和/或每年)的统计数据是必要的。查询文档后,已删除的文档将被过滤掉。
我有一项任务要实现such a flow,即:
- 如果文档根本不存在,则应基于提供的属性来创建它。新的文档ID应该返回给用户。如果用户提供了文档ID,则应使用此ID。
- 当文档存在但被标记为已删除时,应取消删除它并提供属性。文档ID应该返回给用户。
- 否则,应生成“重复文档”异常。
例如,如果文档{_id: ObjectId("5e8f2525a68af8514fb05f03"),title: "Investigation",year: 2005,published: true,deleted: true}
存在,那么如果用户请求创建文档:
-
{ title: "Investigation",year: 2005 }
返回了文档{_id: ObjectId("5e8f2525a68af8514fb05f03"),published: true}
-
{ title: "Investigation",published: false }
返回了文档{_id: ObjectId("5e8f2525a68af8514fb05f03"),published: false}
(相应地应用了属性)
到目前为止,我已经提出了以下解决方案(就Spring Mongo而言):
import org.bson.BsonValue;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import static org.springframework.data.mongodb.core.query.Criteria.where;
public void createDocument(UserDocument userDocument) {
Document document = new Document();
mongoTemplate.getConverter().write(userDocument,document);
Set<String> fields = new HashSet<>();
Collections.addAll(fields,"title","year"); // unique index
Query query = new Query();
Update update = new Update();
update.unset("deleted");
document.entrySet().forEach(entry -> {
if (fields.contains(entry.getKey())) {
query.addCriteria(where(entry.getKey()).is(entry.getValue()));
} else {
update.setonInsert(entry.getKey(),entry.getValue());
}
});
UpdateResult result = mongoTemplate.upsert(query,update,"documents");
BsonValue upsertedId = result.getUpsertedId();
if (upsertedId == null) {
if (result.getModifiedCount() == 0) {
throw new DuplicateDocumentException();
}
if (userDocument.getId() == null) {
userDocument.setId(mongoTemplate.findAndReplace(query,userDocument,"document").getId());
}
} else {
userDocument.setId(upsertedId.asObjectId().getValue().toHexString());
}
}
我想知道给定的解决方案是否最佳?例如,它对数据库进行了两次调用(upsert
和findAndReplace
),这可以在一个查询中完成吗?如果未确认UpdateResult
,该解决方案是否有效?
稍微相关:
- Get ID of affected document by using update()
- Collection.upsert doesn't return _id if Document was only updated
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)