Запрос к метаданным MongoDB GridFS (Java)

Я пытаюсь получить список файлов GridFS, запросив поле метаданных. Например, я получил файловый документ GridFS, который выглядит так:

{ "_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 по вложенным атрибутам?


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


Ответы (3)


К сожалению, мне не удалось заставить его работать с вложенными объектами BasicDBObject.

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

// This query fetches the files I need
BasicDBObject query = new BasicDBObject("metadata.target_field", "abcdefg"));
List<GridFSDBFile> files = gridFs.find(query);
person sebastian    schedule 24.04.2012
comment
Спасибо за ответ на свой вопрос. У меня было подобное затруднительное положение, и ваш ответ помог мне их решить. - person Ganesh Krishnan; 03.09.2012

Из документации 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")));
person Francesca Merighi    schedule 17.12.2014
comment
Будьте осторожны при использовании этого кода. Он сглаживает весь запрос, включая такие операторы, как $in или $nin. Я считаю, что для здравомыслия команды разработчиков этого следует избегать и с самого начала писать запросы в точечной нотации. - person madmuffin; 05.07.2017

Проще:

GridFSDBFile gridFile = fsDocs.findOne(new BasicDBObject("md5","1b21bc40a456befc7d2ee10b0e25fabf"));
person Tiago Pereira    schedule 31.12.2014
comment
Возможно, вы могли бы объяснить, чем этот код лучше или проще, как вы говорите, вместо того, чтобы заставлять читателей пытаться понять, почему? - person William Price; 31.12.2014
comment
Проблема заключалась не в том, чтобы получить файл по его коду md5, а в том, чтобы найти файл по свойству, которое находится в части метаданных. Это свойство иерархически ниже metatdata и md5, что было реальной проблемой. - person sebastian; 07.01.2015