Mongodb 如何将Scala案例类转换为mongo文档

Mongodb 如何将Scala案例类转换为mongo文档,mongodb,scala,Mongodb,Scala,我想构建一个通用方法,用于将Scala案例类转换为Mongo文档 有希望的是 我可以将一个case类转换为Map[String->Any],但是我已经丢失了使用隐式转换为bsonvalue所需的类型信息。也许TypeTags能帮上忙 以下是我尝试过的: import org.mongodb.scala.bson.BsonTransformer import org.mongodb.scala.bson.collection.immutable.Document import org.mongod

我想构建一个通用方法,用于将Scala案例类转换为Mongo文档

有希望的是

我可以将一个case类转换为Map[String->Any],但是我已经丢失了使用隐式转换为bsonvalue所需的类型信息。也许TypeTags能帮上忙

以下是我尝试过的:

import org.mongodb.scala.bson.BsonTransformer
import org.mongodb.scala.bson.collection.immutable.Document
import org.mongodb.scala.bson.BsonValue

case class Person(age: Int, name: String) 

//transform scala values into BsonValues
def transform[T](v: T)(implicit transformer: BsonTransformer[T]): BsonValue = transformer(v)

// turn any case class into a Map[String, Any]
def caseClassToMap(cc: Product) = { 
  val values = cc.productIterator
  cc.getClass.getDeclaredFields.map( _.getName -> values.next).toMap
}

// transform a Person into a Document
def personToDocument(person: Person): Document = {  
  val map = caseClassToMap(person)

  val bsonValues = map.toSeq.map { case (key, value) =>
    (key, transform(value))
  }

  Document.fromSeq(bsonValues)
}

<console>:24: error: No bson implicit transformer found for type Any. Implement or import an implicit BsonTransformer for this type.
           (key, transform(value))
import org.mongodb.scala.bson.BsonTransformer
导入org.mongodb.scala.bson.collection.immutable.Document
导入org.mongodb.scala.bson.BsonValue
案例类人员(年龄:整数,姓名:字符串)
//将scala值转换为BsonValues
def transform[T](v:T)(隐式转换器:BsonTransformer[T]):BsonValue=transformer(v)
//将任何case类转换为Map[String,any]
def caseclastomap(cc:Product)={
val values=cc.productIterator
cc.getClass.getDeclaredFields.map(u.getName->values.next).toMap
}
//将某人转换为文档
def personToDocument(person:person):Document={
val映射=案例类映射(个人)
val bsonValues=map.toSeq.map{case(key,value)=>
(键,变换(值))
}
Document.fromSeq(bsonValues)
}
:24:错误:找不到任何类型的bson隐式转换器。实现或导入此类型的隐式BsonTransformer。
(键,变换(值))
您可以使用沙拉。这里可以找到一个很好的例子-。这是一段可以帮助您的代码-

import salat._

val dBObject = grater[Artist].asDBObject(artist)
artistsCollection.save(dBObject, WriteConcern.Safe)

我能够使用org.bson.BsonDocumentWriter将案例类序列化到BsonDocument。下面的代码使用scala 2.12和mongo-scala-driver_2.12版本2.6.0运行

我对这个解决方案的探索得到了这个答案的帮助(他们正试图以相反的方向序列化):


下面的代码不需要手动转换对象

import reactivemongo.api.bson.{BSON, BSONDocument, Macros}

case class Person(name:String = "SomeName", age:Int = 20)

implicit val personHandler = Macros.handler[Person]

val bsonPerson = BSON.writeDocument[Person](Person())

println(s"${BSONDocument.pretty(bsonPerson.getOrElse(BSONDocument.empty))}")

这是一个糟糕的实际解决方案。我可以想象,只有在我按小时付费的情况下,我才会这样做。链接到解决方案是受欢迎的,但请确保您的答案在没有它的情况下是有用的:这样您的其他用户就会知道它是什么以及为什么存在,然后引用您链接到的页面的最相关部分,以防目标页面不可用。
import salat._

val dBObject = grater[Artist].asDBObject(artist)
artistsCollection.save(dBObject, WriteConcern.Safe)
import org.mongodb.scala.bson.codecs.Macros
import org.mongodb.scala.bson.codecs.DEFAULT_CODEC_REGISTRY
import org.bson.codecs.configuration.CodecRegistries.{fromRegistries, fromProviders}
import org.bson.codecs.EncoderContext
import org.bson.BsonDocumentWriter
import org.mongodb.scala.bson.BsonDocument
import org.bson.codecs.configuration.CodecRegistry
import org.bson.codecs.Codec

case class Animal(name : String, species: String, genus: String, weight: Int)

object TempApp {

  def main(args: Array[String]) {

    val jaguar = Animal("Jenny", "Jaguar", "Panthera", 190)

    val codecProvider = Macros.createCodecProvider[Animal]()
    
    val codecRegistry: CodecRegistry = fromRegistries(fromProviders(codecProvider), DEFAULT_CODEC_REGISTRY)

    val codec = Macros.createCodec[Animal](codecRegistry)

    val encoderContext = EncoderContext.builder.isEncodingCollectibleDocument(true).build()

    var doc = BsonDocument()

    val writr = new BsonDocumentWriter(doc) // need to call new since Java lib w/o companion object

    codec.encode(writr, jaguar, encoderContext)

    print(doc)

  }

};

import reactivemongo.api.bson.{BSON, BSONDocument, Macros}

case class Person(name:String = "SomeName", age:Int = 20)

implicit val personHandler = Macros.handler[Person]

val bsonPerson = BSON.writeDocument[Person](Person())

println(s"${BSONDocument.pretty(bsonPerson.getOrElse(BSONDocument.empty))}")