Reactive Mongo:在Reactive Mongo中同步多个查询的麻烦

时间:2015-03-26 07:52:26

标签: multithreading mongodb scala playframework-2.3 reactivemongo

我正在使用Reactive Mongo ScalaPlay-Framework。我需要点击多个查询来更新结果并检索更新的结果。但是在反应中我们所有的查询都在不同的线程中工作,有时我需要同步查询。如何使用Reactive Mongo实现此目的。 Follwoing是我的代码:

def videoDetails(videoId: String) = Action.async{
logger.info("In videoDetails controller method");

var videoIds: List[JsObject] = CustomUtility.convertStringIdToJsonCriteria(List[String]{videoId});
var query = Json.obj("_id" -> Json.obj("$in" -> videoIds));
var cursor: Cursor[Video] = videosCollection.find(query).cursor[Video];
var future: Future[Option[Video]] = cursor.headOption;
var hitCount: Future[Int] = future.map { videos => {
  if(!videos.isEmpty){
    videos.get.hitCount.get
  }else {
    0;
  }
}}
hitCount.flatMap { count => {
  videosCollection.update(query, Json.obj("$set" -> Json.obj("hitCount" -> (count+1)))).map{ lastError =>
      logger.debug(s"Successfully updated with LastError: $lastError");
    }
  var cursor: Cursor[Video] = videosCollection.find(query).cursor[Video];
  var future: Future[Option[Video]] = cursor.headOption;
  future.map { option => {
   if(!option.isEmpty) Ok(Json.toJson(option.get)) else Ok(Json.toJson(""))
  }}
}}
}

在上面的代码中,首先我使用查询获取记录命中数,并在将来的地图中,创建更新查询以更新我的命中记录数。记录更新后,需要获取docuemnt的最新详细信息。但是按照上面的代码。在每次命中控制器时,该数据都不包含在内。因为有些,如果所有线程一个接一个地运行,那么resule是好的,结果是不对的,因为所有线程都运行asyn。我们如何处理同步的所有线程?

Reactie Mongo中,对于创建DTO也是一个问题,有些时间数据会出现但有时却没有。

更新

从@cchantep的回答我更新我的代码如下:

def videoDetails(videoId: String) = Action.async{
logger.info("In videoDetails controller method");

var videoIds: List[JsObject] = CustomUtility.convertStringIdToJsonCriteria(List[String]{videoId});
var query = Json.obj("_id" -> Json.obj("$in" -> videoIds));
var cursor: Cursor[Video] = videosCollection.find(query).cursor[Video];
for{
  hitCount <- cursor.headOption
  _ <- Promise.successful(hitCount.map { video => {
        videosCollection.update(query, Json.obj("$set" -> Json.obj("hitCount" -> (video.hitCount.get+1)))).map{ lastError =>
            logger.debug(s"Successfully updated with LastError: $lastError");
          }
      }}).future
  resultVideo <- cursor.headOption
  result <- Promise.successful(resultVideo.map { video => {
              Ok(Json.toJson(video))
            }}).future
}yield result.getOrElse(NotFound)
}

但数据仍不同步。有时候我会在video对象中返回chages而有些时候没有。

1 个答案:

答案 0 :(得分:1)

您可以使用for-comprehension对Mongo操作进行排序。

for {
  a <- colA.find(...)
  b <- colB.find(...)
  _ <- colB.update(..., ...)
  c <- colB.find(...)//find if update ok
} yield c