是否可以使用mongo-scala-driver macros从mongo db中读取包含案例类中指定字段的其他字段的文档?
我希望在反序列化时忽略案例类中但未在文档中指定的字段。但抛出异常。由于mongo db的模式较少,因此无法指定案例类中的总字段集。
我想要反序列化的文档看起来像这个json:
{
"_id": 6,
"nestedOne": {
"nestedOneOne": 123,
"nestedOneTwo": 456
},
"nestedTwo": {
"nestedTwoOne": 789
}
}
我希望以下最小的例子能够发挥作用:
import org.bson.codecs.configuration.CodecRegistries.{fromProviders, fromRegistries}
import org.bson.codecs.configuration.CodecRegistry
import org.mongodb.scala.bson.codecs.DEFAULT_CODEC_REGISTRY
import org.mongodb.scala.bson.codecs.Macros._
import org.mongodb.scala.model.Filters
import org.mongodb.scala.MongoClient
import org.mongodb.scala.bson.collection.immutable.Document
import scala.concurrent.Await
import scala.concurrent.duration._
// prepare the case classes and register them
case class TestDocument(_id: Int, nestedOne: Option[NestedOne])
case class NestedOne(nestedOneOne: Int, nestedOneTwo: Int)
val testCodecRegistry: CodecRegistry = fromRegistries(
fromProviders(classOf[TestDocument], classOf[NestedOne]),
DEFAULT_CODEC_REGISTRY
)
// prepare the test data & insert them
val testDocument = Document(
"_id" -> 6,
"nestedOne" -> Document("nestedOneOne" -> 123, "nestedOneTwo" -> 456),
"nestedTwo" -> Document("nestedTwoOne" -> 789)
)
val mongoClient = MongoClient("mongodb://localhost:1234")
val database = mongoClient.getDatabase("testdatabase")
val testCollection = database.getCollection("test_collection").withCodecRegistry(testCodecRegistry)
Await.result(testCollection.insertOne(testDocument).toFuture, 2.minutes)
// try to read and deserialize the document again
val _ = Await.result(testCollection.find[TestDocument](Filters.equal("_id", 6)).toFuture(), 2.minutes)
但抛出以下异常:
head of empty list
java.util.NoSuchElementException: head of empty list
at scala.collection.immutable.Nil$.head(List.scala:428)
at scala.collection.immutable.Nil$.head(List.scala:425)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.readDocument(MacroCodec.scala:204)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.readDocument$(MacroCodec.scala:193)
at de.peterschrott.mongotest.MongoTest$$anon$1$TestDocumentMacroCodec$3.readDocument(MongoTest.scala:29)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.readValue(MacroCodec.scala:173)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.readValue$(MacroCodec.scala:169)
at de.peterschrott.mongotest.MongoTest$$anon$1$TestDocumentMacroCodec$3.readValue(MongoTest.scala:29)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.decode(MacroCodec.scala:104)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.decode$(MacroCodec.scala:96)
at de.peterschrott.mongotest.MongoTest$$anon$1$TestDocumentMacroCodec$3.decode(MongoTest.scala:29)
at com.mongodb.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52)
at com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:53)
at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)
at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)
at org.bson.codecs.configuration.LazyCodec.decode(LazyCodec.java:47)
at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)
at com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:56)
at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)
at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)
at com.mongodb.connection.ReplyMessage.<init>(ReplyMessage.java:57)
at com.mongodb.connection.CommandProtocol.getResponseDocument(CommandProtocol.java:139)
at com.mongodb.connection.CommandProtocol.access$000(CommandProtocol.java:51)
at com.mongodb.connection.CommandProtocol$CommandResultCallback.callCallback(CommandProtocol.java:271)
at com.mongodb.connection.ResponseCallback.onResult(ResponseCallback.java:48)
at com.mongodb.connection.ResponseCallback.onResult(ResponseCallback.java:23)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection$2.onResult(DefaultConnectionPool.java:470)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection$2.onResult(DefaultConnectionPool.java:464)
at com.mongodb.connection.UsageTrackingInternalConnection$3.onResult(UsageTrackingInternalConnection.java:119)
at com.mongodb.connection.UsageTrackingInternalConnection$3.onResult(UsageTrackingInternalConnection.java:115)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.connection.InternalStreamConnection.executeCallbackAndReceiveResponse(InternalStreamConnection.java:378)
at com.mongodb.connection.InternalStreamConnection.access$1700(InternalStreamConnection.java:66)
at com.mongodb.connection.InternalStreamConnection$ResponseBuffersCallback.onResult(InternalStreamConnection.java:420)
at com.mongodb.connection.InternalStreamConnection$ResponseBuffersCallback.onResult(InternalStreamConnection.java:389)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback.onSuccess(InternalStreamConnection.java:562)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback.access$2200(InternalStreamConnection.java:517)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback$ResponseBodyCallback.onResult(InternalStreamConnection.java:584)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback$ResponseBodyCallback.onResult(InternalStreamConnection.java:568)
at com.mongodb.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:447)
at com.mongodb.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:444)
at com.mongodb.connection.AsynchronousSocketChannelStream$BasicCompletionHandler.completed(AsynchronousSocketChannelStream.java:218)
at com.mongodb.connection.AsynchronousSocketChannelStream$BasicCompletionHandler.completed(AsynchronousSocketChannelStream.java:201)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker.invokeDirect(Invoker.java:157)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.implRead(UnixAsynchronousSocketChannelImpl.java:553)
at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:276)
at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:297)
at com.mongodb.connection.AsynchronousSocketChannelStream.readAsync(AsynchronousSocketChannelStream.java:125)
at com.mongodb.connection.InternalStreamConnection.readAsync(InternalStreamConnection.java:444)
at com.mongodb.connection.InternalStreamConnection.access$2000(InternalStreamConnection.java:66)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback.onResult(InternalStreamConnection.java:541)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback.onResult(InternalStreamConnection.java:517)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:447)
at com.mongodb.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:444)
at com.mongodb.connection.AsynchronousSocketChannelStream$BasicCompletionHandler.completed(AsynchronousSocketChannelStream.java:218)
at com.mongodb.connection.AsynchronousSocketChannelStream$BasicCompletionHandler.completed(AsynchronousSocketChannelStream.java:201)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.finishRead(UnixAsynchronousSocketChannelImpl.java:430)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.finish(UnixAsynchronousSocketChannelImpl.java:191)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.onEvent(UnixAsynchronousSocketChannelImpl.java:213)
at sun.nio.ch.KQueuePort$EventHandlerTask.run(KQueuePort.java:301)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
有没有办法解决已解决的问题?
答案 0 :(得分:1)
问题是由于不同的数据类型:
case class TestDocument(_id: Long, nestedOne: Option[NestedOne])
case class NestedOne(nestedOneOne: Int, nestedOneTwo: Int)
val testCodecRegistry: CodecRegistry = fromRegistries(
fromProviders(classOf[TestDocument], classOf[NestedOne]),
DEFAULT_CODEC_REGISTRY
)
具有以下数据形状:
Document("_id" -> 6L,
"nestedOne" -> Document("nestedOneOne" -> 1, "nestedOneTwo" -> 2))
您正在插入此数据形状:
Document(
"_id" -> 6L,
"nestedOne" -> List(Document("nestedOneOne" -> 123)),
"nestedTwo" -> List(Document("nestedTwoOne" -> 789))
)
所以结果是错误,我添加了SCALA-319来改善在这种情况下引发的错误。