0

我正在使用Reactive Mongo版本0.11.11,並且我想在我的DAO中實現一個方法,其中所有文檔的計數均爲_id特性BSONFormats中的BSONObjectIDFormat已棄用

這裏是我的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))) 
    } 

} 

的問題是,我得到以下錯誤:

value BSONObjectIDFormat in trait BSONFormats is deprecated: Use [[reactivemongo.play.json.BSONFormats.BSONObjectIDFormat]] 
[error]  teams.count(Some(Json.obj("_id" -> _id))) 

我試着更換count方法:

def count(_id: BSONObjectID): Future[Int] = { 
teams.count(Some(BSONDocument("_id" -> _id))) 
} 

但那麼我得到以下編譯錯誤:

[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))) 

回答

1

您在混合JSONCollection和BSON值。

建議您使用JSON serializationJSONCollection,或者使用默認BSON serializationBSONCollection

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可以從Play插件中解析,如下所示。

reactiveMongoApi.database.map(_.collection[BSONCollection]("players")) 

The functions MongoConnection.(db|apply) and/or ReactiveMongoApi.db are deprecated, and the equivalent .database must be used (which returns Future[DefaultDB] instead of DefaultDB).

+0

謝謝您的幫助!我正在使用Silhouette,我需要將'LoginInfo'作爲'Player'文檔的一部分。現在問題是,在類LoginInfo中只有'隱式val jsonFormat = Json.format [LoginInfo]',因此我得到一個類型錯誤,因爲我現在正在處理BSON而不是JSON。你有什麼想法,如果我可以做一個JSON的BSON或我錯過了什麼? –

+0

那麼,我現在處理BSON的唯一原因是因爲我需要以某種方式映射'_id'。不幸的是,'BSONObjectID'沒有JSON替代品,是嗎? –

+0

如果您閱讀[doc](http://reactivemongo.org/releases/0.11/documentation/json/overview.html),您可以看到在使用JSON時,「BSONObjectID」的表示形式是「JsObject」用'$ oid',那個轉換就是'import reactivemongo.play.json._'提供的。 – cchantep