2013-08-22 48 views
0

。目前,我有一些代碼,假設如下所示:在斯卡拉/ Scalatra的使用卡斯巴來查詢我是如何從MongoDB的在我的Scalatra的項目中使用卡斯巴單個文檔略有迷茫的文檔

get ("/dogs") { 
    val collar_id = params.getOrElse("collar_id", 1) 
    val mongoColl = mongoDb("pets")("dogs")  
    val o: DBObject = MongoDBObject("collar_id" -> collar_id) 
    val b = mongoColl.findOne(o) 

    b.json_document 
} 

在這種情況下,該文件b有一個擁有所有我需要的響應作爲JSON得到呈現的數據的json_document領域。問題是,我似乎沒有在這裏使用Casbah正確地查詢MongoDB。我要如何查詢此使用MongoDB的客戶端將是等價的:

db.dogs.findOne({collar_id: 5})

什麼是寫我上面的查詢代碼來獲得類似的結果正確的方法是什麼?以字符串形式傳遞collar_id或Int似乎不起作用。同樣在返回b.json_document得到一個錯誤:

value json_document is not a member of Option[mongoColl.T] 

回答

1

是PARAMS圖的整數或字符串?如果var collar_id是一個字符串,但在查詢時將其存儲爲int,將不會找到任何結果。

下面是確保collar_id一個例子是基於則params的Map[string, Any]有效的int:

val collar_id = params.getOrElse("collar_id", "1").toString match { 
    case x if x.forall(Character.isDigit) => x.toInt 
    case _ => 1 
} 
+0

如果我使用int或string,則無關緊要,它們都沒有所需的行爲。 – randombits

+0

錯過了選項部分 - 'findOne'返回一個'Option',因此您需要調用'.get'來獲得實際的文檔 – Ross

1

您可以使用getAs方法上params值:

get("/api/dogs/:collarId") { 

    val query = for { 
    collarId <- params.getAs[Long]("collarId") 
    collar <- mongoColl.findOne(MongoDBObject("collar_id" -> collarId)) 
    } yield collar 

    query match { 
    case Some(x) => x 
    case None => halt(404) 
    } 

} 

這工作還偉大的scalaz的\/類型:

get("/api/dogs/:collarId") { 

    for { 
    collarId <- params.getAs[Long]("collarId") \/> BadRequest() 
    collar <- mongoColl.findOne(MongoDBObject("collar_id" -> collarId)) \/> NotFound() 
    } yield collar 

}