2012-04-27 2 views
10

Я очень новичок в MongoDB, и я использую его вместе с драйвером Java. У меня есть этот документ структуру:Получить поддокумент в массиве как DBObject (ы)

{ "_id" : ObjectId("4f7d2ba6fd5a306d82687d48"), "room" : "Den" } 
{ "_id" : ObjectId("4f7d2baafd5a306d82687d49"), "room" : "Foyer" } 
{ "_id" : ObjectId("4f7d2fdcfd5a306d82687d4a"), "room" : "Master Bedroom" } 
{ "_id" : ObjectId("4f7d301afd5a306d82687d4b"), "room" : "Guest Bedroom" } 
{ "_id" : ObjectId("4f7d2b98fd5a306d82687d47"), "code" : "A", "lights" : [ { "name" : "Overhead", "code" : "1" } ], "room" : "Kitchen" } 

Если последняя строка представляет особый интерес, иллюстрирующий то, что я хочу сделать. Каждый документ является комнатой и может иметь ключ «огни», соответствующий значению, представляющему собой массив поддокументов. С точки зрения моделирования у меня есть дом, в котором есть 0-n номеров, каждый из которых имеет в нем 0-n огней. То, что я хочу сделать на Java, - это имя комнаты в качестве параметра и вернуть коллекцию DBObject, соответствующую поддокументам в массиве огней, - «дайте мне все огни для комнаты« кухня », например ,

До сих пор идет по нарастающей в стиле TDD, я построил этот запрос:.

public static final String ROOM_KEY = "room"; 

public static final String EQUALS_KEY = "$eq"; 

private BasicDBObject buildRoomNameQuery(String roomName) { 

    BasicDBObject myQuery = new BasicDBObject(); 
    myQuery.put(ROOM_KEY, new BasicDBObject(EQUALS_KEY, roomName)); 

    return myQuery; 
} 

Я понимаю, что это собирается получить меня весь документ номера для имени номер я прохожу в I» m немного застрял на том, что лучший способ исходить отсюда - получить то, что я хочу. Является ли то, что я делаю, даже возможно с помощью простого запроса, или мне нужно будет получить массив и перебрать его в код, наведя элементы как DBObject? Я также открыт для предложений по лучшей структуре документов для моей цели - я не женат на этой структуре любыми способами.

Для некоторой точки зрения, я довольно хорошо разбираюсь в SQL и традиционных реляционных базах данных, если это помогает с точки зрения объяснительных аналогов. Кроме того, если я разучиваю терминологию MongoDB, пожалуйста, исправьте меня. Заранее спасибо.

ответ

19

Таким образом, вы можете сделать что-то вроде этого:

DBCollection coll = db.getCollection("test"); 
BasicDBObject query = new BasicDBObject("room", "Kitchen"); 

// optional, limit the fields to only have the lights field 
BasicDBObject fields = new BasicDBObject("lights",1).append("_id",false); 
DBCursor curs = coll.find(query, fields); 
while(curs.hasNext()) { 
    DBObject o = curs.next(); 

    // shows the whole result document 
    System.out.println(o.toString()); 
    BasicDBList lights = (BasicDBList) o.get("lights"); 

    // shows the lights array -- this is actually a collection of DBObjects 
    System.out.println(lights.toString()); 

    // optional: break it into a native java array 
    BasicDBObject[] lightArr = lights.toArray(new BasicDBObject[0]); 
    for(BasicDBObject dbObj : lightArr) { 
    // shows each item from the lights array 
    System.out.println(dbObj); 
    } 
} 

Кроме того, я рекомендую использовать QueryBuilder в драйвере Java - это немного более кратким, чем создание запросов от DBObjects. Еще лучше, проверьте Morphia, который является объектом mapper, который использует драйвер Java. Он изначально поддерживает модели сущностей, у которых есть списки в них, и сериализует/десериализует их в Mongo, без необходимости иметь дело с материалом DBObject.

+0

Спасибо за указатели! Посмотрите более подробно, когда я вернусь домой (вот где этот код). –

+1

Мне нравится свободный интерфейс QueryBuilder, и Morphia выглядит очень мощным. Я думаю, что я буду придерживаться подхода в вашем примере кода, пока не узнаю, что я делаю, а затем, вероятно, перейду в QueryBuilder, а затем в Morphia. Мне всегда нравится понимать это «старомодным способом» и знать, что я сокращаю, прежде чем принять ярлык. –

+0

Это не работает, поскольку вы не можете отбросить BasicDBList в DBObject. – shreks7

1

Посмотрите на пакет весны mongo. Действительно хороший способ работы с Монго использованием POJO документов

http://www.springsource.org/spring-data/mongodb

Вам не нужно будет выполнить отливку и работать со строками

1

Вы можете использовать итератор для полей

Iterator<DBObject> fields = curs.iterator(); 
      while(fields.hasNext()){ 
       DBObject field = (DBObject) fields.next().get("lights"); 
       System.out.println(field.get("name")); 
      } 
0

Для более новых версий рассмотрите использование Document. Чтобы избежать непроверенных слепков и предупреждение ЛИНТЕРА, наряду с написания своего собственного цикла, используйте метод get(final Object key, final Class<T> clazz) в libary в:

List<Document> comments = posts.get("comments", docClazz) 

где docClazz является то, что вы создаете один раз:

final static Class<? extends List> docClazz = new ArrayList<Document().getClass(); 
Смежные вопросы