我对如何在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]
答案 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
}