更新/插入文档的最佳流程

问题描述

假设我有一个文档集合,每个文档都具有以下属性集:

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());
    }
}

我想知道给定的解决方案是否最佳?例如,它对数据库进行了两次调用upsertfindAndReplace),这可以在一个查询中完成吗?如果未确认UpdateResult,该解决方案是否有效?

稍微相关:

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...