Search code examples
mongodbreactivemongoplay-reactivemongo

ReactiveMongo: How to select more than one document from a collection randomly?


I've found this example... but it shows how to select one document from a collection randomly, while I need to select more than one document and as efficiently as possible.


Solution

  • Here below is my solution:

    def listRandom(selector: JsValue, resNum: Int): Future[List[User]] = {    
      userService.count(selector).flatMap {
        case n if n > 0 =>
          val perPage = resNum * 10
          val randomPage = Random.nextInt(math.max(1, n / perPage))
          context.find(selector, None, None, randomPage, perPage).map { users =>
            Random.shuffle(users) take resNum
          }
       case _ => Future.successful(Seq.empty[User])
      }
    }
    

    listRandom takes a selector and an Int that specifies how many results should be returned.

    First it determines how many documents the collection actually contains; then it multiplies resNum by 10 (this is the page size) and determines the number of pages. Finally, it selects one page randomly and shuffles the result.

    I hope it helps.