2012-04-23 23 views
9

Điều tôi đang cố gắng tìm nạp danh sách các tệp GridFS bằng cách truy vấn một trường siêu dữ liệu. Ví dụ: tôi có tài liệu tệp GridFS giống như:Truy vấn trên siêu dữ liệu MongoDB GridFS (Java)

{ "_id" : { "$oid" : "4f95475f5ef4fb269dbac954"} , "chunkSize" : 262144 , "length" : 3077 , "md5" : "f24ea7ac05c5032f08808c6faabf413b" , "filename" : "file_xyz.txt" , "contentType" : null , "uploadDate" : { "$date" : "2012-04-23T12:13:19.606Z"} , "aliases" : null , "metadata" : { "target_field" : "abcdefg"}} 

Và tôi muốn truy vấn tất cả các tệp có chứa "target_field" = "abcdefg". Tôi đã tạo truy vấn của mình như sau:

BasicDBObject query = new BasicDBObject("metadata", new BasicDBObject("target_field", "abcdefg")); 
// gridFS Object Initialization skipped 
List<GridFSDBFile> files = gridFs.find(query); 

Danh sách này là rỗng. Nếu không, việc truy vấn tên tệp hoặc uploadDate sẽ hoạt động hoàn hảo. Không phải là nó có thể nhận được các tập tin GridFS bởi các thuộc tính lồng nhau?

+0

Nó có thể có thể là bạn sai chính tả cái gì? Điều này hoạt động tốt trên máy tính của tôi. Tôi đang sử dụng mongod 2.0.4 và v2.7.3 cho trình điều khiển Java. – Ren

Trả lời

15

Rất tiếc, tôi không làm cho nó hoạt động với các BasicDBObject lồng nhau.

Cuối cùng tôi đã sử dụng các ký hiệu dấu chấm mà hoạt động tốt:

// This query fetches the files I need 
BasicDBObject query = new BasicDBObject("metadata.target_field", "abcdefg")); 
List<GridFSDBFile> files = gridFs.find(query); 
+1

Cảm ơn bạn đã trả lời câu hỏi của riêng bạn. Tôi đã có một tình trạng khó khăn tương tự và câu trả lời của bạn đã giúp tôi giải quyết chúng. –

0

Từ tài liệu MongoDB (http://docs.mongodb.org/manual/tutorial/query-documents/#exact-match-on-the-embedded-document):

Exact Match trên Document Embedded

Để xác định một trận đấu bình đẳng trên toàn bộ tài liệu được nhúng, sử dụng tài liệu truy vấn {:} trong đó tài liệu cần khớp. Các đối sánh bình đẳng trên một tài liệu được nhúng đòi hỏi một sự khớp chính xác của quy định, bao gồm cả thứ tự trường.

Đối sánh bình đẳng trên các trường trong tài liệu được nhúng

Sử dụng ký hiệu chấm để khớp với các trường cụ thể trong tài liệu được nhúng. Đối sánh bình đẳng cho các trường cụ thể trong tài liệu được nhúng sẽ chọn tài liệu trong bộ sưu tập nơi tài liệu được nhúng chứa các trường được chỉ định với các giá trị được chỉ định. Tài liệu được nhúng có thể chứa các trường bổ sung.


Tôi đã viết một mã đơn giản để dịch "ký hiệu tài liệu" trong "ký hiệu chấm". Tôi hy vọng nó hữu ích.

protected static void toDottedJson(Object o, String key, DBObject query) { 
    if (o instanceof Map) 
     for (Entry<?, ?> c : ((Map<?, ?>) o).entrySet()) 
      toDottedJson(c.getValue(), key + "." + c.getKey().toString(), 
        query); 
    else 
     query.put(key, o.toString()); 
} 

public static DBObject buildMetadataSearchQuery(DBObject searchQuery) { 
    BasicDBObject metadatSearchQuery = new BasicDBObject(); 
    for (Entry<?, ?> c : ((Map<?, ?>) searchQuery).entrySet()) 
     toDottedJson(c.getValue(), "metadata." 
       + c.getKey().toString(), 
       metadatSearchQuery); 
    return metadatSearchQuery; 
} 

Đối với mục đích của bạn:

List<GridFSDBFile> files = gridFs.find(buildMetadataSearchQuery(new BasicDBObject("target_field", "abcdefg"))); 
+0

Hãy cẩn thận khi sử dụng mã này. Nó làm phẳng toàn bộ truy vấn, bao gồm các toán tử như '$ in' hoặc' $ nin'. Tôi tin rằng sự tỉnh táo của nhóm phát triển, điều này nên tránh và các truy vấn được viết bằng ký hiệu chấm từ đầu. – madmuffin

0

đơn giản:

GridFSDBFile gridFile = fsDocs.findOne(new BasicDBObject("md5","1b21bc40a456befc7d2ee10b0e25fabf")); 
+2

Có lẽ bạn có thể giải thích cách mã này tốt hơn hoặc đơn giản hơn, như bạn nói, thay vì làm cho người đọc cố gắng tìm ra lý do tại sao? –

+0

Sự cố không phải là tìm nạp tệp theo mã md5 của nó nhưng tìm tệp theo thuộc tính nằm trong phần siêu dữ liệu. Thuộc tính này phân cấp dưới metatdata và md5 đã là vấn đề thực tế. – sebastian

Các vấn đề liên quan