2012-05-06 12 views
7

Ok, ecco un'altra domanda sulle basi di Casbah e MongoDB. Dopo che ho recuperato un DBObject dal database, come posso estrarre determinati dati da esso? So che esiste il metodo DBObject.get(), che restituisce java.lang.Object. Devo farlo in questo modo e quindi basta trasmettere i dati al tipo richiesto? Non sono sicuro che questo sia il modo migliore per farlo ... qualcuno può raccomandare su come farlo meglio?Casbah Scala MongoDB driver - acquisizione dati da un DBObject

UPDATE:

Infine sono andato il modo di gestire manualmente tutte le cose. Non sto utilizzando Salat a causa della limitazione della classe case perché le classi di casi non sono consigliate per avere figli e questo richiederebbe un riarrangiamento architettonico. Tuttavia, la risposta è contrassegnata come la risposta migliore, poiché funzionerebbe nella maggior parte delle situazioni e non c'è altra risposta più generale qui.

risposta

11

È possibile utilizzare il metodo di MongoDBObject as per ottenere il valore e gettato in una sola chiamata:

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.. 

noti che as genera un'eccezione se la chiave data non può essere trovata. È possibile utilizzare getAs che vi dà Option[A]:

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

Estrazione è un po 'più complicato:

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

ho scritto un aiutante, che rende l'utilizzo casbah più consice, può essere che sarà utile, così ho attaccarlo:

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) 

} 

è possibile utilizzare helper in questo modo:

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

Spero che ti possa aiutare.

+0

Wow che copre l'argomento molto bene! Grazie, questo è ovviamente scelto come la migliore risposta. – noncom

+0

Ottiene 'valore getAs non è un membro di Option [coll.T]' quando si chiama 'val obj = coll.findOne (query); val str = obj.getAs [String] ("myValue") '. –

+0

L'esempio non funziona, 'findOne' restituisce un tipo' Option'. – andyczerwonka

2

Se non si ha paura di utilizzare dipendenze aggiuntive, utilizzare Salat. Con Salat è molto semplice eseguire il cast delle classi di casi su oggetti di database e viceversa.

serializzazione

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

deserializzazione

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

Sì, so di Salat ... non ho paura di usare le dipendenze, ma alcuni problemi potrebbero essere presentati dal requriement della classe case. Se non ci saranno altre risposte significative, dovrò guardare in Salat allora ... ma le case-class possono aver bisogno di cambiare l'architettura. – noncom

+0

Non funziona con Scala 2.10 – expert

Problemi correlati