2014-10-28 43 views
1

我正在編寫一個使用MongoDB作爲數據庫和ReactiveMongo作爲驅動程序的Scala Web應用程序。MongoDB在已經存在的情況下更新文檔ReactiveMongo

我有一個名爲recommendation.correlation的集合,其中我保存了產品和類別之間的關聯。

文檔具有以下形式:

{ "_id" : ObjectId("544f76ea4b7f7e3f6e2db224"), "category" : "c1", "attribute" : "c3:p1", "value" : { "average" : 0, "weight" : 3 } } 

現在我正在寫一個方法如下:

def calculateCorrelation: Future[Boolean] = { 
    def calculate(category: String, tag: String, similarity: List[Similarity]): Future[(Double, Int)] = { 
     println("Calculate correlation of " + category + " " + tag) 
     val value = similarity.foldLeft(0.0, 0)((r, c) => if(c.tag1Name.split(":")(0) == category && c.tag2Name == tag) (r._1 + c.eq, r._2 + 1) else r 
      ) //fold the tags 
     val sum = value._1 
     val count = value._2 
     val result = if(count > 0) (sum/count, count) else (0.0, 0) 
     Future{result} 

    } 

    play.Logger.debug("Start Correlation") 
    Similarity.all.toList flatMap { tagsMatch => 
    val tuples = 
    for { 
     i<- tagsMatch 
    } yield (i.tag1Name.split(":")(0), i.tag2Name) // create e List[(String, String)] containing the category and productName 
    val res = tuples map { el => 
     calculate(el._1, el._2, tagsMatch) flatMap { value => 
     val correlation = Correlation(el._1, el._2, value._1, value._2) // create the correlation 
     val query = Json.obj("category" -> value._1, "attribute" -> value._2) 
     Correlations.find(query).one flatMap(element => element match { 
      case Some(x) => Correlations.update(query, correlation) flatMap {status => status match { 
      case LastError(ok, _, _, _, _, _, _) => Future{true} 
      case _ => Future{false} 
      } 

      } 
      case None => Correlations.save(correlation) flatMap {status => status match { 
      case LastError(ok, _, _, _, _, _, _) => Future{true} 
      case _ => Future{false} 
      } 

      } 
     } 
      ) 

     } 

    } 

    val result = if(res.exists(_ equals false)) false else true 
    Future{result} 
    } 

的問題是,該方法插入複製文件。 爲什麼會發生這種情況?

我已經解決了使用db.recommendation.correlation.ensureIndex({"category": 1, "attribute": 1}, {"unique": true, "dropDups":true }),但我怎樣才能解決這個問題,而不使用索引?

怎麼回事?

回答

2

你想要做的是就地更新。要使用ReactiveMongo做到這一點,您需要使用update operator來告訴它哪些字段要更新,以及如何更新。相反,你已經通過correlation(我認爲是某種BSONDocument)到集合的更新方法。這只是要求替換文檔,如果唯一索引值不同將導致將新文檔添加到集合中。而不是通過correlation你應該通過一個BSONDocument使用update operators之一,如$ set(設置一個字段)或$ incr(增加一個數字字段)。有關詳細信息,請參閱MongoDB Documentation, Modify Document

相關問題