Запитване за метаданни на 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)


За съжаление не го накарах да работи с вложени BasicDBObjects.

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

// 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