Search code examples
scalaplayframeworkreactivemongoplay-reactivemongo

Canonical implementation of findAndDelete using ReactiveMongo


Using ReactiveMongo, what would be the canonical way to find a single document using a query, delete this document and finally return it. I am also using the ReactiveMongo plugin for the Playframework. So far, I have come up with the following snippet:

def removeOne(query: JsObject)(implicit collection: JSONCollection): Future[Option[MyModel]] = {
  collection.remove(query, firstMatchOnly = true).map(result => result match {
    case success if result.ok => ???
    case failure => throw new RuntimeException(failure.message)
  })
}

The key question is a) Does the LastError contain the single document and b) how can it be transformed to an Option of MyModel class.


Solution

  • There is no shortcut for "find and remove" in reactivemongo, like there is for the crud operations etc, but I think you can do it using the db.commands method and the FindAndModify like this:

     val db: DefaultDB = ???
     import reactivemongo.core.commands._
     db.command(
       FindAndModify("collection",
         query = BSONDocument("something" -> "somevalue"),
         modify = Remove
       )
     ).map(maybeDoc =>
       maybeDoc.map(BSON.readDocument[SomeType])
     )
    

    BSON.readDocument implicitly takes reader that can parse SomeType out of BSON. The result of the operation and then map will be a Future[Option[SomeType]]