查询MongoDB GridFS?

问题描述:

我有一个博客系统,可以将上传的文件存储到GridFS系统中。问题是,我不明白如何查询它!查询MongoDB GridFS?

我正在使用Mongoose和NodeJS,它还不支持GridFS,所以我使用实际的MongoDB模块进行GridFS操作。没有SEEM是一种查询文件元数据的方式,就像您在常规集合中查看文档一样。

将元数据存储在指向GridFS objectId的文档中是否明智?轻松就能查询?

任何帮助,将不胜感激,即时通讯有点粘:/

GridFS通过为每个文件存储一些块工作。这样,您可以交付和存储非常大的文件,而无需将整个文件存储在RAM中。此外,这使您可以存储大于最大文档大小的文件。推荐的块大小为256kb。

文件元数据字段可用于存储其他文件特定的元数据,这比将元数据存储在单独的文档中效率更高。这很大程度上取决于您的具体要求,但元数据字段通常提供了很大的灵活性。请记住,一些比较明显的元数据已经是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。最有效的方法是将数据流逐块传输到客户端,因此您不必将整个文件加载到RAM中。该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 */ 
} 

如果你想使用的fs.files为您查询metadata场,请确保您了解dot notation,例如

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

还确保您的查询可以使用索引使用explain()

+0

如何创建在元数据字段上创建可用索引? – 2015-06-17 12:21:08

+0

你可以简单地创建一个像{fs.files.metadata.my_field:1}这样的索引`没有一个模式大大简化了一些事情 – mnemosyn 2015-06-17 13:26:18

元数据存储在元数据字段。你可以查询它像

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

这可能不是什么OP预计。该语法将查找子文档的*精确*匹配,即您的查询将**不匹配元数据:{“content_type”:“text/html”,“foo”:“bar”}`。另外,这个例子可能会让人困惑,因为`content_type`是`fs.files`结构的一部分,但是在那里有不同的名字。 – mnemosyn 2011-12-15 09:30:42

正如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"}); 

我知道这个问题不问关于查询的元数据的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()); 
}