Question

I have the following code:

  def all: String = {

    val query = BSONDocument("name" -> BSONDocument("$ne" -> "allDocs"))

    val cursor = carsCollection.find(query).cursor[BSONDocument]
    Logger.debug("Before cursor")
    cursor.enumerate.apply(Iteratee.foreach {
      doc =>
        Logger.debug("found document: " + doc.getAs[BSONString]("name").get.value)
        //Logger.debug("found document: " + doc.getAs[BSONString]("area").get.value)
    })
    "Ok"
  }

When I run this code the play console shows the field "name" of 12 different documents coming from mongodb. When I uncomment the second Logger call, the system prints only one name and it stops. The field "area" exists in the db without problems.

Am I doing something wrong?

Was it helpful?

Solution

My guess is that doc.getAs[BSONString]("area").get.value throws some exception.

You should test if there is a value and what is the type of the value to be sure:

cursor.enumerate.apply(Iteratee.foreach { doc =>
  // ...
  doc.getAs[BSONString]("area") match {
    case Some(BSONString(area)) => Logger.debug(s"area is BSONString of value = $area")
    case None => Logger.debug("area does not exist or is not a BSONString"
  }
}

The getAs[BSONString] method returns an Option[BSONString]. If there is a value, but this value could not be parsed as a BSONString – in other words, when the value is not a BSONString but rather a BSONInteger, BSONLong, BSONDocument, etc. – then None is returned. Since you call get on it, without checking if the option is defined or not, it might throw a NoSuchElementException.

Another way of doing this:

cursor.enumerate.apply(Iteratee.foreach { doc =>
  // ...
  doc.get("area") match {
    case Some(BSONString(area)) => Logger.debug(s"area is a BSONString of value = $area")
    case Some(otherBSONValue) => Logger.debug(s"area exists but is not a BSONString: $otherBSONValue")
    case None => Logger.debug("area does not exist or is not a BSONString"
  }
}

If there is an exception in your iteratee, the final future may be in error.

val future = cursor.enumerate |>>> Iteratee.foreach { doc =>
  Logger.debug("found document: " + doc.getAs[BSONString]("name").get.value)
  Logger.debug("found document: " + doc.getAs[BSONString]("area").get.value)
}
future.onComplete {
  case Success(_) => Logger.debug("successful!")
  case Failure(e) => Logger.debug(s"there was an exception! ${e.getMessage}")
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top