Использование Casbah в Scala/Scalatra для запроса документа
Я немного запутался в том, как извлечь отдельный документ из MongoDB, используя Casbah в моем проекте 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_document
поле, содержащее все данные, которые мне нужны, чтобы получить в ответе как JSON. Проблема в том, что я, кажется, не обращаюсь к MongoDB должным образом, используя Casbah. Эквивалент того, как я бы запросил это, используя клиент 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 ответа
Params - это карта целых или строк? Если вар collar_id
является строкой, но вы сохраняете ее как int, когда запрашиваете ее, не найдете никаких результатов.
Вот пример обеспечения collar_id
является действительным Int на основе параметров Map[string, Any]
:
val collar_id = params.getOrElse("collar_id", "1").toString match {
case x if x.forall(Character.isDigit) => x.toInt
case _ => 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)
}
}
Это также прекрасно работает со скалярными \ / type:
get("/api/dogs/:collarId") {
for {
collarId <- params.getAs[Long]("collarId") \/> BadRequest()
collar <- mongoColl.findOne(MongoDBObject("collar_id" -> collarId)) \/> NotFound()
} yield collar
}