2017-06-19 5 views
0

mongo-scala-driver macrosを使用して、ケースクラスで指定されたフィールドに追加のフィールドを含むmongo dbのドキュメントを読み取ることはできますか?Mongo Scalaドライバマクロを使用して、追加のネストされたフィールドを持つドキュメントを読み取る

私は、ケースクラスでは指定されていないが、ドキュメント内のフィールドはデシリアライズ時に無視されると予想しました。しかし、例外がスローされます。スキーマが少ないmongo dbのアプローチのために、ケースクラスのフィールドの合計セットを指定することは不可能です。

私はデシリアライズしたいドキュメントが、このJSONのようになります。

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) 

をしかし、次の例外がスローされます:私は仕事に、次の最小限の例を期待

{ 
    "_id": 6, 
    "nestedOne": { 
     "nestedOneOne": 123, 
     "nestedOneTwo": 456 
    }, 
    "nestedTwo": { 
     "nestedTwoOne": 789 
    } 
} 

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

関数fromRegistries、waitForResultおよびfromProvidersがありません。また、変数データベースがありません。 –

+0

テスト・ドキュメントが、ケース・クラスで表される予想されるデータ構造と一致しません。エラーメッセージが改善される可能性があります。今後、追加する予定です。 – Ross

答えて

1

問題は、異なるデータ型にある:

Document("_id" -> 6L, 
     "nestedOne" -> Document("nestedOneOne" -> 1, "nestedOneTwo" -> 2)) 

あなたは、このデータ形状挿入されています:だから結果は

Document(
    "_id" -> 6L, 
    "nestedOne" -> List(Document("nestedOneOne" -> 123)), 
    "nestedTwo" -> List(Document("nestedTwoOne" -> 789)) 
) 

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 
) 

は、次のデータ形状をしていますエラー、この場合にスローされるエラーを改善するためにSCALA-319を追加しました。

+0

私の例で問題が見えます。私は実際に間違いを犯した。そのことを申し訳ありません。 あなたの提案に合わせて、コードではなく私の質問を更新しました。しかし、ドキュメントにケースクラスで指定されていないフィールドがある場合、私はまだ例外を取得します。 – peedeeX21

+2

2.2.0の一部としてリリースされる[SCALA-307](https://jira.mongodb.org/browse/SCALA-307)で修正されました。スナップショットは現在入手可能です。 – Ross

+0

@Rossスナップショットはmavenでは利用できません。このスナップショットに依存性を追加する方法についてのヒント?私は、私のケースクラスにObjectIdフィールドを含めていない、コーデックマクロは、 "空のリストの先頭"の例外で動作しません。 –