微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MongoDB Scala 驱动程序如何仅更新案例类对象中更改的文档字段

如何解决MongoDB Scala 驱动程序如何仅更新案例类对象中更改的文档字段

我有以下案例类:

  @GQLDirective(federation.Key("User Config"))
case class UserConfig(
                        userId: Int,personalGroup: Option[PersonalGroup] = None,accountGroup: Option[AccountGroup] = None
                       ) extends Bson {
    override def toBsonDocument[TDocument](documentClass: Class[TDocument],codecRegistry: CodecRegistry): BsonDocument = {
      new BsonDocumentWrapper[UserConfig](this,codecRegistry.get(classOf[UserConfig]))
    }
  }

并尝试以这种方式更新已存储的文档:

def update(userConfig: UserConfig) = {
    collection.updateOne(equal("userId",1),userConfig).headOption()
  }

但是当我尝试这样做时,出现以下错误Invalid BSON field name userId

我也尝试过使用 replaceOne 方法,但它会替换整个对象并删除我不想删除的字段。

我想要达到的目标: 我只想在 mongodb 文档中保存更改的字段。这些字段由 graphql 请求提供

解决方法

现在,我找到了一种方法来转换和递归合并新对象和旧对象,就像这样。如果有人有更好的代码或意见 - 我很乐意聊天

val firstJson =  parse(userConfigFromRequest.toBsonDocument(classOf[UserConfig],codecRegistry).toJson).extract[Map[String,Any]]
val secondJson = parse(config.toBsonDocument(classOf[UserConfig],Any]]
val merged = deepMerge(firstJson,secondJson)

  def deepMerge(
                 map1: Map[String,Any],map2: Map[String,accum: MutableMap[String,Any] = MutableMap[String,Any]()
               ): MutableMap[String,Any] = {
    map1 foreach {
      case (key,value: Map[String,Any]) => {
        map2.get(key) match {
          case Some(oldValue: Map[String,Any]) => {
            accum.put(key,deepMerge(value,map2,MutableMap(oldValue.toSeq: _*) ))
          }
          case None => accum.put(key,value)
        }
      }
      case (key,value) => {
        accum.put(key,value)
      }
    }
    accum
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。