2012-04-23 3 views
9

То, что я пытаюсь сделать, это собрать список файлов GridFS, запросив поле метаданных. Например, я получил GridFS файл документ выглядит как:Запрос на 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"}} 

И я хочу, чтобы запросить все файлы, содержащие «target_field» = «ABCDEFG». Я создал свой запрос следующим образом:

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

Список всегда пуст. В противном случае запрос имени файла или uploadDate работает отлично. Невозможно ли получить файлы GridFS вложенными атрибутами?

+0

Может быть, возможно, вы неправильно что-то? Это отлично работает на моей машине. Я использую mongod 2.0.4 и v2.7.3 для Java-драйвера. – Ren

ответ

15

К сожалению, я не получил его для работы с вложенными объектами BasicDBObjects.

Наконец я использовал обозначение точек, которая работает отлично:

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

Спасибо, что ответили на ваш собственный вопрос. У меня было подобное затруднительное положение, и ваш ответ помог мне решить их. –

0

От MongoDB документации (http://docs.mongodb.org/manual/tutorial/query-documents/#exact-match-on-the-embedded-document):

точного соответствие внедренного документа

Чтобы указать матч равенства на весь внедренный документ, используйте документ запроса {:}, где должен соответствовать документ. Соотношения равенства в встроенном документе требуют точного соответствия указанному, включая порядок полей.

Равенство матч на полях в вложенном документе

Используйте точечную нотацию, чтобы соответствовать по конкретным областям во встроенном документе. Сопоставления равенства для определенных полей во встроенном документе будут выбирать документы в коллекции, где встроенный документ содержит указанные поля с указанными значениями. Вложенный документ может содержать дополнительные поля.


Я написал простой код перевести «документ обозначения» в «точечной нотации». Надеюсь, это полезно.

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

Для вашей цели:

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

Будьте внимательны при использовании этого кода. Он выравнивает весь запрос, включая операторы типа '$ in' или' $ nin'. Я считаю, что для здравомыслия команды разработчиков, этого следует избегать и запросов, написанных в точечной нотации с самого начала. – madmuffin

0

Simpler:

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

Возможно, вы могли бы объяснить, как этот код лучше или проще, как вы говорите, вместо того, чтобы читатели пытались понять, почему? –

+0

Проблема заключалась не в том, чтобы получить файл по его коду md5, но найти файл по свойству, находящемуся внутри части метаданных. Это свойство иерархически ниже метаданных и md5, которые были реальной проблемой. – sebastian

Смежные вопросы