Scala:如何将嵌套案例 类 映射到 ReactiveMongo 查询的日期字段?
Scala: How to map nested cases classes with Date field for ReactiveMongo query?
我有两个案例 类,用户 1 -> N 关键字,我想在 Scala 中使用 ReactiveMongo 进行查询和更新。
这里是类:
case class Keyword(
keyword: String,
var lastUpdate: Date,
var counter: Int)
object Keyword {
implicit val keywordWriter: OWrites[Keyword] = (
(JsPath \ "keyword").write[String] and
(JsPath \ "lastUpdate").write[Date] and
(JsPath \ "counter").write[Int])(unlift(Keyword.unapply))
implicit val keywordReader: Reads[Keyword] = (
(JsPath \ "keyword").read[String] and
(JsPath \ "lastUpdate").read[Date] and
(JsPath \ "counter").read[Int])(Keyword.apply _)
}
case class User(
_id: Option[BSONObjectID],
name: String,
lastname: String,
twitterUser: String,
var keywords: Option[Seq[Keyword]] = None)
object User {
implicit val userWriter: OWrites[User] = (
(JsPath \ "_id").writeNullable[BSONObjectID] and
(JsPath \ "name").write[String] and
(JsPath \ "lastname").write[String] and
(JsPath \ "twitterUser").write[String] and
(JsPath \ "keywords").writeNullable[Seq[Keyword]])(unlift(User.unapply))
implicit val userReader: Reads[User] = (
(JsPath \ "_id").readNullable[BSONObjectID] and
(JsPath \ "name").read[String] and
(JsPath \ "lastname").read[String] and
(JsPath \ "twitterUser").read[String] and
(JsPath \ "keywords").readNullable[Seq[Keyword]])(User.apply _)
// implicit val userFormatter = Json.format[User]
}
写入部分没问题,因为我看到这个 类 生成的 MongoDB 文档模型,在用户集合的关键字字段中的嵌套文档列表。
问题出现在读取部分,当我 运行 这个错误是:
play.api.libs.json.JsResultException: JsResultException(errors:List((/keywords(0)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(1)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(2)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(3)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(4)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray())))))
at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:61)
at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:33)
at reactivemongo.core.protocol.ReplyDocumentIterator$.$anonfun$parse(protocol.scala:141)
at scala.collection.Iterator$$anon.next(Iterator.scala:455)
at scala.collection.Iterator$ConcatIterator.next(Iterator.scala:226)
at reactivemongo.api.DefaultCursor$Impl.$anonfun$headOption(DefaultCursor.scala:332)
at scala.concurrent.Future$.$anonfun$apply(Future.scala:654)
at scala.util.Success.$anonfun$map(Try.scala:251)
at scala.util.Success.map(Try.scala:209)
at scala.concurrent.Future.$anonfun$map(Future.scala:288)
at scala.concurrent.impl.Promise.liftedTree1(Promise.scala:29)
at scala.concurrent.impl.Promise.$anonfun$transform(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run(BatchingExecutor.scala:91)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
我也试过只放:
implicit val keywordFormatter = Json.format[关键字]
隐式 val userFormatter = Json.format[用户]
但是结果一样。
有人可以帮我解决这个问题吗?
提前致谢!
使用 BSONDateTime 而不是 Date
import play.api.libs.json._
import play.api.libs.functional.syntax._
import reactivemongo.bson.BSONDateTime
import reactivemongo.play.json.BSONFormats._
case class Keyword(
keyword: String,
lastUpdate: BSONDateTime,
counter: Int)
object Keyword {
implicit val keywordWriter = new OWrites[Keyword]{
override def writes(keyword: Keyword): JsObject = Json.obj(
"keyword" -> keyword.keyword,
"lastUpdate" -> keyword.lastUpdate,
"counter" -> keyword.counter,
)
}
implicit val keywordReader: Reads[Keyword] = (
(JsPath \ "keyword").read[String] and
(JsPath \ "lastUpdate").read[BSONDateTime] and
(JsPath \ "counter").read[Int])(Keyword.apply _)
}
我有两个案例 类,用户 1 -> N 关键字,我想在 Scala 中使用 ReactiveMongo 进行查询和更新。
这里是类:
case class Keyword(
keyword: String,
var lastUpdate: Date,
var counter: Int)
object Keyword {
implicit val keywordWriter: OWrites[Keyword] = (
(JsPath \ "keyword").write[String] and
(JsPath \ "lastUpdate").write[Date] and
(JsPath \ "counter").write[Int])(unlift(Keyword.unapply))
implicit val keywordReader: Reads[Keyword] = (
(JsPath \ "keyword").read[String] and
(JsPath \ "lastUpdate").read[Date] and
(JsPath \ "counter").read[Int])(Keyword.apply _)
}
case class User(
_id: Option[BSONObjectID],
name: String,
lastname: String,
twitterUser: String,
var keywords: Option[Seq[Keyword]] = None)
object User {
implicit val userWriter: OWrites[User] = (
(JsPath \ "_id").writeNullable[BSONObjectID] and
(JsPath \ "name").write[String] and
(JsPath \ "lastname").write[String] and
(JsPath \ "twitterUser").write[String] and
(JsPath \ "keywords").writeNullable[Seq[Keyword]])(unlift(User.unapply))
implicit val userReader: Reads[User] = (
(JsPath \ "_id").readNullable[BSONObjectID] and
(JsPath \ "name").read[String] and
(JsPath \ "lastname").read[String] and
(JsPath \ "twitterUser").read[String] and
(JsPath \ "keywords").readNullable[Seq[Keyword]])(User.apply _)
// implicit val userFormatter = Json.format[User]
}
写入部分没问题,因为我看到这个 类 生成的 MongoDB 文档模型,在用户集合的关键字字段中的嵌套文档列表。 问题出现在读取部分,当我 运行 这个错误是:
play.api.libs.json.JsResultException: JsResultException(errors:List((/keywords(0)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(1)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(2)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(3)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(4)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray())))))
at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:61)
at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:33)
at reactivemongo.core.protocol.ReplyDocumentIterator$.$anonfun$parse(protocol.scala:141)
at scala.collection.Iterator$$anon.next(Iterator.scala:455)
at scala.collection.Iterator$ConcatIterator.next(Iterator.scala:226)
at reactivemongo.api.DefaultCursor$Impl.$anonfun$headOption(DefaultCursor.scala:332)
at scala.concurrent.Future$.$anonfun$apply(Future.scala:654)
at scala.util.Success.$anonfun$map(Try.scala:251)
at scala.util.Success.map(Try.scala:209)
at scala.concurrent.Future.$anonfun$map(Future.scala:288)
at scala.concurrent.impl.Promise.liftedTree1(Promise.scala:29)
at scala.concurrent.impl.Promise.$anonfun$transform(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run(BatchingExecutor.scala:91)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
我也试过只放: implicit val keywordFormatter = Json.format[关键字] 隐式 val userFormatter = Json.format[用户]
但是结果一样。
有人可以帮我解决这个问题吗?
提前致谢!
使用 BSONDateTime 而不是 Date
import play.api.libs.json._
import play.api.libs.functional.syntax._
import reactivemongo.bson.BSONDateTime
import reactivemongo.play.json.BSONFormats._
case class Keyword(
keyword: String,
lastUpdate: BSONDateTime,
counter: Int)
object Keyword {
implicit val keywordWriter = new OWrites[Keyword]{
override def writes(keyword: Keyword): JsObject = Json.obj(
"keyword" -> keyword.keyword,
"lastUpdate" -> keyword.lastUpdate,
"counter" -> keyword.counter,
)
}
implicit val keywordReader: Reads[Keyword] = (
(JsPath \ "keyword").read[String] and
(JsPath \ "lastUpdate").read[BSONDateTime] and
(JsPath \ "counter").read[Int])(Keyword.apply _)
}