scalareactivemongo

ReactiveMongo Type Mismatched with Sort Method


I am writing a generic find method for used by different classes.

def _find[T](selector: Option[BSONDocument], sorter: Option[BSONDocument], projection: Option[BSONDocument])
  (implicit reader: BSONDocumentReader[T], collectionName: String): Future[List[T]] = {
  val _sorter: reactivemongo.bson.BSONDocument = sorter.getOrElse(reactivemongo.bson.BSONDocument())
  for {
    collection <- database.map(_.collection(collectionName))
    r <- collection.find(selector.getOrElse(BSONDocument()))
      // .sort(sorter.getOrElse(reactivemongo.bson.BSONDocument()))  // this does not compile
      .sort(_sorter)
      .projection(projection.getOrElse(BSONDocument()))
      .cursor[T]().collect[List](Int.MaxValue, Cursor.FailOnError[List[T]]())
  } yield (r)
}

The selector, sorter and projection are all optional, but the sort() method failed if I include getOrElse as part of the argument and I have to "get" the sorter value outside the find() method. I am using ReactiveMongo 0.19.2 and Scala 2.12 now and the above code did compile with ReactiveMongo 0.16.0 and Scala 2.11. The compilation error is as following.

> [error] ......: type mismatch; [error]  found   : Object [error] 
> required: reactivemongo.api.bson.BSONDocument [error]          
>           .sort(sorter.getOrElse(reactivemongo.bson.BSONDocument())) [error]    
>                                 ^

Solution

  • Following does compile not using deprecated BSON API.

    import scala.concurrent._
    
    import reactivemongo.api._
    import reactivemongo.api.bson._ // !!
    
    implicit def ec: ExecutionContext = ???
    def database: Future[DefaultDB] = ???
    
    def _find[T](selector: Option[BSONDocument], sorter: Option[BSONDocument], projection: Option[BSONDocument])
      (implicit reader: BSONDocumentReader[T], collectionName: String): Future[List[T]] = {
    
     for {
        collection <- database.map(_.collection(collectionName))
        r <- collection.find(selector.getOrElse(BSONDocument()))
          .sort(sorter.getOrElse(BSONDocument.empty))  // DOES COMPILE
          .projection(projection.getOrElse(BSONDocument()))
          .cursor[T]().collect[List](Int.MaxValue, Cursor.FailOnError[List[T]]())
      } yield (r)
    }
    

    Without imports related with original code I can only guess it's a bad mix of old/new API (see documentation about compat).