2013-03-15 3 views
0

Я думаю, что вокруг должно быть простое решение, но я не смог его найти.MongoDB + Scala: доступ к глубоким вложенным данным

Я начинаю доступ к данным из MongoDB следующее в Scala:

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 [String], хотя здесь это не работает ... У кого-нибудь есть идея? В поисках решения в течение нескольких часов ...

ответ

0

Я думаю, вы должны попробовать

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

Это простое решение, которое я искал! Спасибо, отлично работает. :-) –

+0

Я подозреваю, что существует менее подробное решение. Вы можете попробовать 'memberInfo.as [MongoDBList] (« member »). As (0)' и посмотреть, может ли он вывести тип. – anoopelias

+0

Также да, салат - это путь в конечном итоге. Это элегантная обертка над касбахом. – anoopelias

2

Если вы работаете со сложными объектами MongoDB, вы можете использовать Salat, который обеспечивает простой случай класс сериализацию.
Sample с данными:

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

Звучит интересно. Не могли бы вы привести краткий пример, в котором были бы адресованы более глубокие вложенные данные? –

+0

Это выглядит очень многообещающим и четко структурированным. В долгосрочной перспективе я пойду за этим. Но для решения моей неотложной проблемы ответ от аноопелии короткий и прекрасный. Я хотел бы повысить ваш пост, но сначала я должен получить некоторую репутацию ... сделаю задачу для этого позже! :-) Еще раз спасибо! –

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