Question

The code sends a request to MongoDB using ReactiveMongo and returns Future[BSONDocument] but my code handles lists of data, so I need to get the value of Future[BSONDocument] and then turn it into a list.

How do I do that preferably without blocking?

Upadte:

I am using ReactiveMongo RawCommand

 def findLByDistance()(implicit ec: ExecutionContext) =  db.command(RawCommand(
        BSONDocument(
            "aggregate" -> collName,
            "pipeline" -> BSONArray(BSONDocument(
                "$geoNear" -> BSONDocument(
                    "near" -> BSONArray(44.72,25.365),
                    "distanceField" -> "location.distance",
                    "maxDistance" -> 0.08,
                    "uniqueDocs" -> true)))
                )))

And the result comes out in Future[BSONDocument]. For some simple queries I used default query builder which allowed for simple conversion

def findLimitedEvents()(implicit ec: ExecutionContext) =
  collection.find(BSONDocument.empty)
    .query(BSONDocument("tags" -> "lazy"))
    .options(QueryOpts().batchSize(10))
    .cursor.collect[List](10, true)

I basically I need the RawCommand output type to match previously used.

Was it helpful?

Solution 2

You cannot "get" a future without blocking. if you want to wait for a Future to complete then you must block.

What you can do is map a Future into another Future:

val futureDoc: Future[BSONDocument] = ...
val futureList = futureDoc map { doc => docToList(doc) }

Eventually, you'll hit a point where you've combined, mapped, recovered, etc. all your futures and want something to happen with the result. This is where you either block, or establish a handler to do something with the eventual result:

val futureThing: Future[Thing] = ...

//this next bit will be executed at some later time,
//probably on a different thread
futureThing onSuccess {
  case thing => doWhateverWith(thing)
}

OTHER TIPS

Not sure about your exact use-case (showing some more code would help), but it might be useful to convert from List[Future[BSONDocument]] to one Future[List[BsonDocument]], which you can then more easily onSuccess or map on, you can do that via:

val futures: List[Future[A]] = List(f1, f2, f3)
val futureOfThose: Future[List[A]] = Future.sequence(futures)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top