2012-05-06 5 views
7

Итак, вот еще один вопрос об основах Casbah и MongoDB. После того как я удалил DBObject из базы данных, как мне извлечь из него определенные данные? Я знаю, что существует метод DBObject.get(), который возвращает java.lang.Object. Должен ли я сделать это так, а затем просто передать данные в нужный тип? Я не уверен, что это лучший способ сделать это ... может ли кто-нибудь порекомендовать, как это сделать лучше?Casbah Scala MongoDB driver - получение данных из DBObject

UPDATE:

Наконец я пошел путь вручную обработки всех вещей. Я не использую Salat из-за ограничения класса case, потому что классы классов не рекомендуются для того, чтобы иметь детей, и это потребует архитектурной перестройки. Тем не менее, ответ отмечен как лучший ответ, поскольку он будет работать в большинстве ситуаций, и здесь нет другого более общего ответа.

ответ

11

Вы можете использовать as метод MongoDBObject, чтобы получить значение и бросьте в одном вызове:

val coll = MongoConnection()(dbName)(collName) 
val query = MongoDBObject("title" -> "some value") 
val obj = coll findOne query 

val someStr = obj.as[String]("title") 
val someInt = obj.as[Int]("count") 
// and so on.. 

Обратите внимание, что as генерирует исключение, если данный ключ не может быть найден. Вы можете использовать getAs, который дает вам Option[A]:

obj.getAs[String]("title") match { 
    case Some(someStr) => ... 
    case None => ... 
} 

Извлечение списков является немного более сложным:

val myListOfInts = 
    (List() ++ obj("nums").asInstanceOf[BasicDBList]) map { _.asInstanceOf[Int] } 

Я написал помощник, который делает использование касбы более consice, может быть, это будет полезно, поэтому я придаю его:

package utils 

import com.mongodb.casbah.Imports._ 

class DBObjectHelper(underlying: DBObject) { 

    def asString(key: String) = underlying.as[String](key) 

    def asDouble(key: String) = underlying.as[Double](key) 

    def asInt(key: String) = underlying.as[Int](key) 

    def asList[A](key: String) = 
    (List() ++ underlying(key).asInstanceOf[BasicDBList]) map { _.asInstanceOf[A] } 

    def asDoubleList(key: String) = asList[Double](key) 
} 

object DBObjectHelper { 

    implicit def toDBObjectHelper(obj: DBObject) = new DBObjectHelper(obj) 

} 

Вы можете использовать помощника, как это:

val someStr = obj asString "title" 
val someInt = obj asInt "count" 
val myDoubleList = obj asDoubleList "coords" 

Я надеюсь, что это вам поможет.

+0

Ничего себе, который очень хорошо охватывает тему! Спасибо, это, очевидно, теперь выбрано как лучший ответ. – noncom

+0

Я получаю 'значение getAs не является членом Option [coll.T]' при вызове 'val obj = coll.findOne (query); val str = obj.getAs [String] ("myValue") '. –

+0

Пример не работает, 'findOne' возвращает тип' Option'. – andyczerwonka

2

Если вы не боитесь использовать дополнительные зависимости, используйте Salat. С помощью Salat очень просто классифицировать классы case для объекта базы данных и обратно.

сериализация

val dbo = grater[Company].asDBObject(company) 

десериализация

val company_* = grater[Company].asObject(dbo) 
+0

Да, я знаю о Салате ... не боюсь использовать зависимости, но некоторые неприятности могут быть представлены только в вопросе класса case. Если не будет никакого другого значимого ответа, мне придется заглянуть в Салату тогда ... но case-классы могут представлять некоторую потребность в изменении архитектуры. – noncom

+0

Он не работает с Scala 2.10 – expert