I am using Reactive Mongo version 0.11.11 and I want to implement a method in my DAO which counts all documents by _id
.
Here is my DAO:
import com.google.inject.Inject
import models.auth.{Team, Player}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json._
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json._
import reactivemongo.bson._
import reactivemongo.play.json.collection.JSONCollection
import scala.concurrent.Future
trait TeamDao {
def find(_id: BSONObjectID): Future[Option[Team]]
def find(name: String): Future[Option[Team]]
def save(team: Team): Future[Team]
def link(player: Player, team: Team): Future[Team]
def update(team: Team): Future[Team]
def count(team: Option[Team] = None): Future[Int]
def count(_id: BSONObjectID): Future[Int]
def countAllPlayersWithTeam(team: Team): Future[Int]
}
class MongoTeamDao @Inject()(reactiveMongoApi: ReactiveMongoApi) extends TeamDao {
val players = reactiveMongoApi.db.collection[JSONCollection]("players")
val teams = reactiveMongoApi.db.collection[JSONCollection]("teams")
def find(_id: BSONObjectID): Future[Option[Team]] = teams.find(BSONDocument("_id" -> _id)).one[Team]
def find(name: String): Future[Option[Team]] = teams.find(Json.obj("name" -> name)).one[Team]
def save(team: Team): Future[Team] = teams.insert(team).map(_ => team)
def link(player: Player, team: Team) = for {
_ <- players.update(Json.obj("_id" -> player.id), Json.obj("$push" -> BSONDocument("teams" -> team._id)))
team <- find(team._id.get)
} yield team.get
def update(team: Team) = for {
_ <- teams.update(BSONDocument("_id" -> team._id), BSONDocument("$set" -> BSONDocument("name" -> team.name)))
team <- find(team._id.get)
} yield team.get
def count(team: Option[Team] = None): Future[Int] = {
val tmpTeam: Team = team.getOrElse {
return teams.count()
}
teams.count(Some(Json.obj("name" -> tmpTeam.name)))
}
def count(_id: BSONObjectID): Future[Int] = {
teams.count(Some(Json.obj("_id" -> _id)))
}
def countAllPlayersWithTeam(team: Team): Future[Int] = {
players.count(Some(Json.obj("teams" -> team._id)))
}
}
The problem is that I get the following error:
value BSONObjectIDFormat in trait BSONFormats is deprecated: Use [[reactivemongo.play.json.BSONFormats.BSONObjectIDFormat]]
[error] teams.count(Some(Json.obj("_id" -> _id)))
I tried to replace the count
method with:
def count(_id: BSONObjectID): Future[Int] = {
teams.count(Some(BSONDocument("_id" -> _id)))
}
But then I get the following compile error:
[error] found : reactivemongo.bson.BSONDocument
[error] required: MongoTeamDao.this.teams.pack.Document
[error] (which expands to) play.api.libs.json.JsObject
[error] Error occurred in an application involving default arguments.
[error] teams.count(Some(BSONDocument("_id" -> _id)))
You are mixing JSONCollection
and BSON values.
It's recommanded that you either use the JSON serialization with JSONCollection
, or you use the default BSON serialization with BSONCollection
.
The deprecation message is a warning indicating to use the separate JSON library, instead of the former types previously included in the Play plugin.
A BSONCollection
can be resolved from the Play plugin as follows.
reactiveMongoApi.database.map(_.collection[BSONCollection]("players"))
The functions
MongoConnection.(db|apply)
and/orReactiveMongoApi.db
are deprecated, and the equivalent.database
must be used (which returnsFuture[DefaultDB]
instead ofDefaultDB
).