注意:示例是在 Kotlin 中使用 Spring Data MongoDB,利用更新方法,如 https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries 中所述。更新了。
考虑这个实体和存储库:
@Document
data class Foo(
val name: String,
val bars: Set<String> = setOf(),
@Id
val id: String = UUID.randomUUID().toString(),
)
@Repository
interface FooRepository : CoroutineCrudRepository<Foo, String> {
suspend fun saveOrAddBarsFrom(foo: Foo) {
if (findAndAddToSetBarsById(foo.id, foo.bars) == 0) {
save(foo)
}
}
@Update("{ \$addToSet : { 'bars' : { \$each : ?1 } } }")
suspend fun findAndAddToSetBarsById(id: String, bars: Set<String>): Int
}
如果您注意到方法
saveOrAddBarsFrom
,则需要两次往返才能更新插入 Foo
:一次尝试将给定字符串 $addToSet
转换为现有的 Foo
,如果没有更新,则一次往返save
Foo
,因为没有找到它,有效地提供了更新插入行为。
有没有办法制作一种方法,在一次往返中,
save
是一个Foo
(如果它不存在)或将字符串添加到bars
集合(如果存在)?
@Update
查询不采用任何选项来指定文档是否需要更新插入。这是官方文档的链接。
但是,您可以尝试一些更新插入文档,如下所示:
MongoOperations mongoOps = new MongoTemplate(new SimpleMongoClientDbFactory(MongoClients.create(), "database"));
Query query = new Query(Criteria.where("id").is(foo.id));
Update update = new Update().addToSet("bars").each(foo.bars);
Foo upserted = template.update(Foo.class)
.matching(query)
.apply(update)
.withOptions(FindAndModifyOptions.options().upsert(true).returnNew(true))
.findAndModifyValue()
您可以在文档中查看它这里。