我想构建一个将Scala案例类转换为Mongo文档的通用方法。
有希望的Document constructor是
fromSeq(ts: Seq[(String, BsonValue)]): Document
我可以将案例类转换为Map [String - >任何],但后来我丢失了我需要使用隐式转换到BsonValues的类型信息。也许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))
答案 0 :(得分:3)
def personToDocument(person: Person): Document = {
Document("age" -> person.age, "name" -> person.name)
}
答案 1 :(得分:0)
我能够使用org.bson.BsonDocumentWriter将案例类序列化为BsonDocument。以下代码使用scala 2.12和mongo-scala-driver_2.12版本2.6.0运行
我对这个解决方案的追求得到了以下答案的帮助(他们试图以相反的方向进行序列化):Serialize to object using scala mongo driver?
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)
}
};
答案 2 :(得分:0)
以下代码无需手动转换对象即可工作。
/var/www/html/thinopticsnewdesign/app/code/Mageplaza/LayeredNavigation/Model/Resource/Model/Fulltext/Collection.php
答案 3 :(得分:-1)
您可以使用Salat https://github.com/salat/salat。这里有一个很好的例子 - https://gist.github.com/bhameyie/8276017。这是一段可以帮助您的代码 -
import salat._
val dBObject = grater[Artist].asDBObject(artist)
artistsCollection.save(dBObject, WriteConcern.Safe)