mongo-scala-driver部分插入静默失败,posts集合插入不成功原因问询
问题排查与解决方案
优先检查插入操作的异常抛出
你调用Await.result(collection.insertOne(doc).toFuture, Duration.Inf)时未做异常捕获,插入失败大概率是抛出了未捕获的异常,只是你没有感知到。建议用try-catch包裹插入逻辑,打印异常栈:try { val res = Await.result(collection.insertOne(doc).toFuture, Duration.Inf) println(s"插入成功,返回结果:$res") } catch { case e: Exception => e.printStackTrace() }常见的异常原因包括字段序列化失败、集合校验不通过、权限不足等。
确认隐式ExecutionContext是否正确导入
insertOne().toFuture需要传入隐式的ExecutionContext,如果你代码中没有导入scala.concurrent.ExecutionContext.Implicits.global或者自定义的ExecutionContext没有可用线程,会导致Future一直处于pending状态,看起来像静默失败。检查posts集合的Schema校验配置
如果你提前为posts集合配置了校验规则,不符合规则的插入会被拒绝。你可以在Mongo Shell中执行如下命令查看集合配置:db.getCollectionInfos({name: "posts"})重点检查
options.validator规则,以及validationAction配置,如果配置为warn,不符合规则的插入不会抛出异常,只会在服务端打日志,出现你看到的静默失败现象。验证待插入文档的序列化结果
打印你构造的Document的JSON内容,确认字段类型、取值是否符合预期:println(doc.toJson())如果你的
post对象中有自定义类型没有注册对应的MongoDB Codec,会出现序列化失败,或者生成不符合预期的空字段/错误类型字段,导致插入被拒绝。手动验证集合写入权限
使用你代码中配置的MongoDB连接URI登录Shell,手动执行插入测试:use myDatabase db.posts.insertOne({"id": 1, "fromId": 2, "ownerId":3, "publishDate": new Date(), "text": "test", "isPinned": false})如果Shell中也无法插入,说明是服务端的权限、集合配置问题,和代码逻辑无关;如果Shell可以插入,再排查驱动版本、Codec注册等客户端问题。
补充说明:Mongo Scala Driver 4.x的执行逻辑
你提到认为4.x版本不需要订阅Observable触发执行,这个认知有误:异步API返回的Observable默认还是冷流,只有调用subscribe()或者转为Future等待才会触发执行,你用Await.result的方式是正确的,不需要额外订阅。
内容的提问来源于stack exchange,提问作者user7429643

