2012-04-27 22 views
10

Tôi rất mới với MongoDB và tôi đang sử dụng nó cùng với trình điều khiển Java. Tôi có cấu trúc tài liệu này:Truy xuất tài liệu phụ trong mảng dưới dạng DBObject (s)

{ "_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" } 

Trường hợp dòng cuối cùng được quan tâm đặc biệt để minh họa những gì tôi muốn làm. Mỗi tài liệu là một căn phòng và có thể có một "đèn" chìa khóa tương ứng với một giá trị đó là một mảng các tài liệu phụ. Từ quan điểm mô hình hóa, tôi có một ngôi nhà, trong đó có 0-n phòng, mỗi phòng trong số đó có đèn 0-n trong đó. Những gì tôi muốn làm trong Java là lấy tên của phòng như một tham số, và trả về một tập hợp các DBObject tương ứng với các tài liệu phụ trong mảng ánh sáng - "lấy cho tôi tất cả các đèn cho phòng 'nhà bếp'", ví dụ .

Cho đến nay, tiến hành từng bước trong phong cách TDD, tôi đã xây dựng truy vấn này:.

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; 
} 

Tôi nhận ra rằng điều này sẽ làm cho tôi toàn bộ tài liệu phòng cho tên phòng tôi vượt qua trong tôi' m một chút bị mắc kẹt trên những gì cách tốt nhất để tiến hành từ đây là để có được những gì tôi muốn. Là những gì tôi đang làm thậm chí có thể với một truy vấn đơn giản, hoặc tôi sẽ phải lấy mảng và lặp qua nó trong mã, đúc các yếu tố như DBObject? Tôi cũng mở để gợi ý cho một cấu trúc tài liệu tốt hơn cho mục đích của tôi - Tôi không kết hôn với cấu trúc này bằng bất kỳ phương tiện.

Đối với một chút quan điểm, tôi khá thành thạo trong SQL và cơ sở dữ liệu quan hệ truyền thống, nếu điều đó giúp về mặt tương tự giải thích. Ngoài ra, nếu tôi đang xử lý thuật ngữ MongoDB, hãy sửa tôi. Cảm ơn trước.

Trả lời

19

Vì vậy, bạn có thể làm một cái gì đó như thế này:

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); 
    } 
} 

Ngoài ra, tôi khuyên bạn nên sử dụng QueryBuilder trong trình điều khiển Java - đó là chính xác hơn một chút so với việc tạo truy vấn từ DBObjects. Thậm chí tốt hơn, hãy kiểm tra Morphia, một trình ánh xạ đối tượng sử dụng trình điều khiển Java. Nó tự nhiên hỗ trợ các mô hình thực thể có các danh sách trong chúng, và tuần tự hóa/deserializes chúng thành Mongo mà không cần phải xử lý các công cụ DBObject.

+0

Cám ơn các con trỏ! Sẽ xem xét chi tiết hơn khi tôi về nhà (đó là nơi mã này). –

+1

Tôi thích giao diện thông thạo của QueryBuilder, và Morphia trông rất mạnh mẽ. Tôi nghĩ rằng tôi sẽ gắn bó với cách tiếp cận trong mẫu mã của bạn ở đây cho đến khi tôi biết những gì tôi đang làm và sau đó có thể tiến tới QueryBuilder và sau đó Morphia. Tôi luôn luôn hoàn toàn hiểu nó "theo cách cũ kỹ" và biết những gì tôi rút ngắn trước khi tôi lấy phím tắt. –

+0

Điều này không hoạt động vì bạn không thể truyền BasicDBList đến DBObject. – shreks7

1

Bạn có thể sử dụng một iterator cho các lĩnh vực

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

Đối với các phiên bản mới hơn, hãy xem xét việc sử dụng Document. Để tránh dàn diễn viên không được kiểm soát và cảnh báo Linter, cùng với viết vòng lặp của riêng bạn, sử dụng phương pháp get(final Object key, final Class<T> clazz) của THƯ VIỆN:

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

nơi docClazz là một cái gì đó mà bạn tạo ra một lần:

final static Class<? extends List> docClazz = new ArrayList<Document().getClass(); 
Các vấn đề liên quan