ReactiveMongo从0.20.X升级到1.0.7后update.one()类型适配问题如何处理
类型差异原因
ReactiveMongo 1.0.x版本对不同写入操作的返回类型做了分层细化:
insert.one()、delete.one()的返回值仅需要通用写入结果字段,所以直接返回Future[WriteResult]update.one()的返回结果需要承载更新场景独有的matchedCount(匹配文档数)、modifiedCount(更新文档数)、upsertedId(插入生成的ID,仅upsert场景有效)等字段,所以专门定义了UpdateWriteResult作为WriteResult的子类型返回。你看到的(GenericCollection[collection.Pack] with CollectionMetaCommands)#UpdateWriteResult是Scala路径依赖类型的语法表现,本质就是UpdateWriteResult,完全兼容WriteResult的所有通用能力。
使用示例
首先可以手动明确标注方法返回类型,屏蔽复杂的路径依赖类型签名,编译器会自动做类型适配:
import reactiveMongo.api._ import reactivemongo.api.bson._ import reactivemongo.api.bson.collection.BSONCollection import reactivemongo.api.commands.{WriteResult, UpdateWriteResult} // 方案1:明确返回UpdateWriteResult,可使用更新场景独有的字段 def updateAsFuture(collection: BSONCollection, selector: BSONDocument, modifier: BSONDocument, upsert: Boolean = false, multi: Boolean = false): Future[UpdateWriteResult] = { collection.update.one(selector, modifier, upsert = upsert, multi = multi) } // 方案2:如果不需要更新独有字段,可直接标注为通用WriteResult,兼容旧版本逻辑 def updateAsFutureLegacy(collection: BSONCollection, selector: BSONDocument, modifier: BSONDocument, upsert: Boolean = false, multi: Boolean = false): Future[WriteResult] = { collection.update.one(selector, modifier, upsert = upsert, multi = multi) }
调用及结果处理示例:
val userCollection: BSONCollection = ??? // 你的BSON集合实例 // 执行更新:将用户名为zhangsan的用户年龄设置为25 val resultF = updateAsFuture( collection = userCollection, selector = BSONDocument("username" -> "zhangsan"), modifier = BSONDocument("$set" -> BSONDocument("age" -> 25)), upsert = false ) // 异步处理结果 resultF.map { res => if (res.ok) { println(s"匹配文档数:${res.matchedCount},实际更新数:${res.modifiedCount}") res.upsertedId.foreach(id => println(s"upsert生成的文档ID:$id")) } else { println(s"更新失败,错误:${res.writeErrors.map(_.errmsg).mkString(";")}") } }.recover { case e: Exception => println(s"操作异常:${e.getMessage}") }
内容的提问来源于stack exchange,提问作者l33tHax0r
相关产品推荐
相关产品推荐

