ReactiveMongo 查找一个文档错误

ReactiveMongo Find One Document Error

使用以下代码位,我尝试根据用户的电子邮件获取单个文档,其中电子邮件是存储文档的一部分:

  def userByEmail(encryptedEmail: String): Future[Either[ServiceError, User]] = async {

    println(s"finding a user for email $encryptedEmail")

    val inlandDb = dbConn.db(dbName)
    val userColl = inlandDb[BSONCollection](userCollection)
    val found = await(
      userColl.find(BSONDocument(emailKey -> BSONString(encryptedEmail))).one[User]
    )
    println(s"found a user $found")

    found match {
      case Some(user) => Right(user)
      case None => Left(ServiceError("user not found"))
    }
  }

我在 mongo 控制台中验证了给定电子邮件的用户存在。有什么问题吗?为什么我无法让用户返回我的搜索查询。

我是否应该在我的用户文档中为电子邮件定义任何索引以便对其进行搜索?

我收到以下错误:

finding a user for email Ctkiaw/cbW8DxtRIxbtUYADq5bp6uW7tVryhpT57lKU=
failed java.lang.RuntimeException: None.get

None.get
java.lang.RuntimeException: None.get
    at scala.sys.package$.error(package.scala:27)
    at play.api.libs.iteratee.Iteratee$$anonfun$run.apply(Iteratee.scala:396)
    at play.api.libs.iteratee.Iteratee$$anonfun$run.apply(Iteratee.scala:389)
    at play.api.libs.iteratee.StepIteratee$$anonfun$fold.apply(Iteratee.scala:706)
    at play.api.libs.iteratee.StepIteratee$$anonfun$fold.apply(Iteratee.scala:706)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at play.api.libs.iteratee.Execution$trampoline$.executeScheduled(Execution.scala:109)
    at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:71)
    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248)
    at scala.concurrent.Promise$class.complete(Promise.scala:55)
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23)
    at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

这是我的用户模型:

case class User(
  _id: Option[String],
  firstName: String,
  lastName: String,
  email: String,
  pass: String,
  address: Address,
  createDate: DateTime,
  activateDate: Option[DateTime],
  isUserActivated: Boolean,
  verificationDate: Option[DateTime]
)

以下是我进行转换的方法:

  implicit object UserBSONHandler
    extends BSONDocumentReader[User] with BSONDocumentWriter[User] {

    def read(doc: BSONDocument): User = {
      User(
        _id = doc.getAs[String]("_id"),
        createDate = doc.getAs[BSONDateTime](createDateKey).map(dt => new DateTime(dt.value, DateTimeZone.UTC)).get,
        activateDate = doc.getAs[BSONDateTime](activateDateKey).map(dt => new DateTime(dt.value, DateTimeZone.UTC)),
        verificationDate = doc.getAs[BSONDateTime](verificationDateKey).map(dt => new DateTime(dt.value, DateTimeZone.UTC)),
        firstName = doc.getAs[String](firstNameKey).get,
        lastName = doc.getAs[String](lastNameKey).get,
        email = doc.getAs[String](emailKey).get,
        pass = doc.getAs[String](passKey).get,
        address = doc.getAs[Address](addressKey).get,
        isUserActivated = doc.getAs[Boolean](isUserActivatedKey).get
      )
    }
    def write(user: User): BSONDocument = {
      BSONDocument(
        firstNameKey -> user.firstName,
        lastNameKey -> user.lastName,
        emailKey -> user.email,
        passKey -> user.pass,
        addressKey -> user.address,
        createDateKey  -> user.createDate.toString(Iso8601DateFormatter),
        activateDateKey  -> user.activateDate.map(dt => dt.toString(Iso8601DateFormatter)),
        verificationDateKey  -> user.verificationDate.map(dt => dt.toString(Iso8601DateFormatter)),
        isUserActivatedKey  -> user.isUserActivated
      )
    }
  }

从日志来看,您的 Reads 中似乎有问题,上面发布的原始代码在语法上是可以的,但是错误消息以及日志记录代码帮助我在进一步检查您的 BSONDocumentReader

时归零

在 "Barry" 的帮助下,我能够确定问题所在。我不得不如下更改读取方法:

def read(doc: BSONDocument): User = {
  User(
    _id = doc.getAs[String]("_id"),
    createDate = doc.getAs[String](createDateKey).map(dt => new DateTime(dt, DateTimeZone.UTC)).get,
    activateDate = doc.getAs[String](activateDateKey).map(dt => new DateTime(dt, DateTimeZone.UTC)),
    verificationDate = doc.getAs[String](verificationDateKey).map(dt => new DateTime(dt, DateTimeZone.UTC)),
    firstName = doc.getAs[String](firstNameKey).get,
    lastName = doc.getAs[String](lastNameKey).get,
    email = doc.getAs[String](emailKey).get,
    pass = doc.getAs[String](passKey).get,
    address = doc.getAs[Address](addressKey).get,
    isUserActivated = doc.getAs[Boolean](isUserActivatedKey).get
  )
}