2013-03-15 89 views
0

我認爲應該有一個簡單的解決方案,但我無法找到它。MongoDB + Scala:訪問深度嵌套數據

我開始從MongoDB中與斯卡拉以下訪問數據:

val search = MongoDBObject("_id" -> new ObjectId("xxx")) 
val fields = MongoDBObject("community.member.name" -> 1, "community.member.age" -> 1) 

for (res <- mongoColl.find(search, fields)) { 
    var memberInfo = res.getAs[BasicDBObject]("community").get 
    println(memberInfo) 
} 

,並獲得BasicDBObject的結果是:

{ 
"member" : [ 
    { 
     "name" : "John Doe", 
     "age" : "32", 
    },{ 
     "name" : "Jane Doe", 
     "age" : "29", 
    }, 
    ... 
] 
} 

我知道,我可以getAs [字符串]訪問值,雖然這不在這裏工作... 任何人有一個想法?在搜索了幾個小時的解決方案......

回答

0

我想你應該嘗試

val member = memberInfo.as[MongoDBList]("member").as[BasicDBObject](0) 
println(member("name")) 
+1

這是我尋找的簡單解決方案!謝謝,完美的作品。 :-) – 2013-03-15 13:16:44

+0

我懷疑有一個不太詳細的解決方案。你可以試試'memberInfo.as [MongoDBList](「member」)。as(0)',看看它是否可以推斷出類型。 – anoopelias 2013-03-16 09:33:39

+0

另外,是的,salat是他們長遠走的路。這是一個優雅的包裝casbah。 – anoopelias 2013-03-16 09:36:34

2

如果您有複雜的MongoDB的對象時,你可以使用Salat,它提供了簡單的情況下,類的序列。
樣品與您的數據:

case class Community(members:Seq[Member], _id: ObjectId = new ObjectId) 

case class Member(name:String, age:Int) 

val mongoColl: MongoCollection = _ 

val dao = new SalatDAO[Community, ObjectId](mongoColl) {} 

val community = Community(Seq(Member("John Doe", 32), Member("Jane Doe", 29))) 
dao.save(community) 

for { 
    c <- dao.findOneById(community._id) 
    m <- c.members 
} println("%s (%s)" format (m.name, m.age)) 
+0

聽起來很有趣。你能提供一個簡單的例子來解決更深層的嵌套數據嗎? – 2013-03-15 09:12:33

+0

這看起來很有希望,結構清晰。從長遠來看,我會爲此而努力。但爲了解決我的緊急問題,anoopelias的答案很簡短。我想積極發表你的文章,但我必須先獲得一些聲望......稍後將爲此做出一項任務! :-) 再次感謝! – 2013-03-15 13:23:59

0

這個問題並沒有真正與MongoDB的事,而是與您的數據結構。您的JSON/BSON數據結構包括

  • 一個目的社區,其包括
    • 成員
      • 陣列,每個構件具有屬性名稱或年齡。

你的問題是完全等同於以下:

case class Community(members:List[Member]) 

case class Member(name:String, age:Int) 

val a = List(member1,member2) 

// a.name does not compile, name is a property defined on a member, not on the list 
0

是的,你可以用精美的內涵做到這一點。您可以執行以下操作:

for { record <- mongoColl.find(search,fields).toList 
     community <- record.getAs[MongoDBObject]("community") 
     member <- record.getAs[MongoDBObject]("member") 
     name <- member.getAs[String]("name") } yield name 

這只是爲了獲得名稱。要獲得多個值,我認爲你會這樣做:

for { record <- mongoColl.find(search,fields).toList 
     community <- record.getAs[MongoDBObject]("community") 
     member <- record.getAs[MongoDBObject]("member") 
     field <- List("name","age") } yield member.get(field).toString