2011-12-15 2 views
8

У меня есть система ведения блогов, которая хранит загруженные файлы в систему GridFS. Проблема в том, что я не понимаю, как запросить его!Запрос MongoDB GridFS?

Я использую Mongoose с NodeJS, который еще не поддерживает GridFS, поэтому я использую фактический модуль mongodb для операций GridFS. SEEM не является способом запроса метаданных файлов, подобных документам, в регулярной коллекции.

Было бы целесообразным хранить метаданные в документе, указывающем на объект GridFS? легко получить запрос?

Любая помощь будет принята с благодарностью, им любопытное застрял:/

ответ

18

GridFS работы, храня количество блоков для каждого файла. Таким образом, вы можете доставлять и хранить очень большие файлы без необходимости хранить весь файл в ОЗУ. Кроме того, это позволяет хранить файлы, размер которых превышает максимальный размер документа. Рекомендуемый размер блока - 256 КБ.

Поле метаданных файла может использоваться для хранения дополнительных метаданных для файлов, которые могут быть более эффективными, чем хранение метаданных в отдельном документе. Это сильно зависит от ваших точных требований, но поле метаданных в целом предлагает большую гибкость. Имейте в виде, что некоторые из более очевидных метаданных уже часть fs.files документа по умолчанию:

> db.fs.files.findOne(); 
{ 
    "_id" : ObjectId("4f9d4172b2ceac15506445e1"), 
    "filename" : "2e117dc7f5ba434c90be29c767426c29", 
    "length" : 486912, 
    "chunkSize" : 262144, 
    "uploadDate" : ISODate("2011-10-18T09:05:54.851Z"), 
    "md5" : "4f31970165766913fdece5417f7fa4a8", 
    "contentType" : "application/pdf" 
} 

действительно прочитать файл из GridFS вам придется извлечь файл документ из fs.files и куски из fs.chunks. Самый эффективный способ сделать это - передать это клиенту по блоку, поэтому вам не нужно загружать весь файл в ОЗУ. chunks коллекция имеет следующую структуру:

> db.fs.chunks.findOne({}, {"data" :0}); 
{ 
    "_id" : ObjectId("4e9d4172b2ceac15506445e1"), 
    "files_id" : ObjectId("4f9d4172b2ceac15506445e1"), 
    "n" : 0, // this is the 0th chunk of the file 
    "data" : /* loads of data */ 
} 

Если вы хотите использовать metadata поле fs.files для ваших запросов, убедитесь, что вы понимаете dot notation, например,

> db.fs.files.find({"metadata.OwnerId": new ObjectId("..."), 
        "metadata.ImageWidth" : 280}); 

также убедитесь, что ваши запросы могут использовать индекс, используя explain().

+0

Как создать создать полезный индекс в поле метаданных? –

+0

Вы можете просто создать индекс, подобный '{fs.files.metadata.my_field: 1}' Не имея схемы, значительно упрощает некоторые вещи – mnemosyn

0

метаданные хранятся в метаданных области. Вы можете запросить его нравится

db.fs.files.find({metadata: {content_type: 'text/html'}}) 
+3

Это, вероятно, не то, что ОП надеется. Этот синтаксис будет искать * точные * соответствия поддокумента, т. Е. Ваш запрос будет ** не ** соответствовать «метаданным»: {«content_type»: «text/html», «foo»: «bar»} '. Кроме того, пример может запутать, потому что 'content_type' является частью структуры' fs.files', но имеет другое имя. – mnemosyn

6

Как говорится в specification, вы можете хранить все, что захотите, в поле метаданных.

Вот как документ из коллекции файлов выглядит следующим образом:

Обязательные поля

{ 
    "_id" : <unspecified>,     // unique ID for this file 
    "length" : data_number,     // size of the file in bytes 
    "chunkSize" : data_number,    // size of each of the chunks. Default is 256k 
    "uploadDate" : data_date,    // date when object first stored 
    "md5" : data_string      // result of running the "filemd5" command on this file's chunks 
} 

Необязательные поля

{  
    "filename" : data_string,    // human name for the file 
    "contentType" : data_string,   // valid mime type for the object 
    "aliases" : data_array of data_string, // optional array of alias strings 
    "metadata" : data_object,    // anything the user wants to store 
} 

Так хранить все, что вы хотите в метаданных и запросите его, как обычно, в MongoDB:

db.fs.files.find({"metadata.some_info" : "sample"}); 
1

Я знаю, что вопрос не спрашивает о том, как Java в запросе метаданных, но здесь, если вы добавить gender как поле метаданных:

// Get your database's GridFS 
GridFS gfs = new GridFS("myDatabase); 

// Write out your JSON query within JSON.parse() and cast it as a DBObject 
DBObject dbObject = (DBObject) JSON.parse("{metadata: {gender: 'Male'}}"); 

// Querying action (find) 
List<GridFSDBFile> gridFSDBFiles = gfs.find(dbObject); 

// Loop through the results 
for (GridFSDBFile gridFSDBFile : gridFSDBFiles) { 
    System.out.println(gridFSDBFile.getFilename()); 
} 
+0

Почему большие пальцы? – javaauthority