在Scala / Scalatra中使用Casbah查询文档

时间:2013-08-22 02:43:43

标签: mongodb scala scalatra casbah

我对如何在Scalatra项目中使用Casbah从MongoDB中检索单个文档感到有些困惑。目前,我有一些代码假设如下:

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_document字段,其中包含我需要在响应中呈现为JSON的所有数据。问题是,我似乎没有在这里使用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]

2 个答案:

答案 0 :(得分:1)

params是一个整数或字符串的地图?如果var collar_id是一个字符串,但是在查询它时将它存储为int将找不到任何结果。

以下是根据collar_id的参数确保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
}

答案 1 :(得分: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

}