简体   繁体   English

mongodb中的Gridfs

[英]Gridfs in mongodb

Recently we integrated the Gridfs in mongodb for storing images. 最近,我们将Gridfs集成到mongodb中以存储图像。 For my requirement, previously we have used NFS for getting or storing an images in directory. 根据我的要求,以前我们已经使用NFS在目录中获取或存储图像。 its getting more slow down for an images. 对于图像,它变得越来越慢。 So we integrated GridFS. 因此,我们集成了GridFS。

GridFS, but now my clarification is how we can get the more than once images on single request and show it in the browser?. GridFS,但是现在我要澄清的是,如何才能在单个请求中获得多个图像,并在浏览器中显示它? Because we populated near to 1L photos in mongodb gridfs sharding. 因为我们在mongodb gridfs分片中填充了接近1L的照片。 But i cant fetch the more than one images on single request. 但是我无法在单个请求中获取多个图像。

Sample Code given below. 下面给出了示例代码。 - Following code will return only one photos. -以下代码将仅返回一张照片。 I cant fetch the all images on single request. 我无法在单个请求中获取所有图像。 If anyone face this kind of issues, pls share us. 如果有人遇到此类问题,请与我们分享。

Method 1: It returns only one image. 方法1:它只返回一张图像。

$mongo = new Mongo("192.168.0.8:27017");
$db = $mongo->myfiles;
$gridFS = $db->getGridFS();
$cursor = $gridFS->find()->limit(10); - it will return one than one images
/*$cursor  = $gridFS->find(array("metadata.memberid"=>"CMD34123")); - it will return one than one images, because the member having more than one images.*/

foreach ($cursor as $obj)
{                   
        header("Content-Type: image/jpg");
        $stream = $obj->getResource();

        while (!feof($stream)) {
                echo fread($stream, 51200);
        }
}

Method 2: It returns all images, but same like NFS each image will fetch each HTTP request. 方法2:它返回所有图像,但与NFS一样,每个图像将获取每个HTTP请求。 No saving. 没有保存。

$mongo = new Mongo("192.168.0.8:27017");
$db = $mongo->myfiles;
$gridFS = $db->getGridFS();
$cursor = $gridFS->find()->limit(10);
foreach ($cursor as $obj)
       echo "<img src='getphoto.php?filename=".$obj->getFilename()."'>";

getphoto.php: getphoto.php:

$mongo = new Mongo("192.168.0.8:27017");
$db = $mongo->myfiles;
$gridFS = $db->getGridFS();
/*$image = $gridFS->findOne($_REQUEST['filename']);*/
header("Content-Type: image/jpg");
echo $stream = $image->getResource();
while (!feof($stream)) 
        echo fread($stream, 51200);

I don't see how you would return multiple files in a single request unless you were using one of PHP's compression and archive extensions to combine them into a single file, which in turn was relayed as the HTTP response. 我看不到如何在单个请求中返回多个文件,除非您使用PHP的压缩和归档扩展名之一将它们组合为一个文件,然后将其作为HTTP响应中继。

If the images are small, an alternative would be embedding them in HTML as base64-encoded Data URIs . 如果图像较小,则可以选择将它们嵌入HTML中,作为base64编码的Data URI That technique is often used for embedding small images (icon size) in CSS background-image values; 该技术通常用于在CSS background-image值中嵌入小图像(图标大小)。 however, it's not suitable for large images, since the storage overhead is quite high. 但是,由于存储开销非常大,因此它不适用于大图像。


Regarding this query in your first code example: 关于第一个代码示例中的此查询:

$gridFS->find(array("metadata.memberid"=>"CMD34123"))

I realize this line was commented out, but if you are running such a query, I would suggest indexing metadata.memberid to avoid scanning each document in the fs.files collection. 我知道这一行已被注释掉,但是如果您正在运行这样的查询,我建议为metadata.memberid编制索引,以避免扫描fs.files集合中的每个文档。

The iteration you were doing attempts to print a content-type header and byte contents of several JPG images in succession. 您正在进行的迭代尝试连续打印几个 JPG图像的内容类型标题和字节内容。 PHP's header() function cannot be called multiple times in this manner. 不能以这种方式多次调用PHP的header()函数。

You may be able utilize multi-part HTTP responses to send back multiple images, but browser support could be problematic (see: this question from a few years back ). 您可能可以使用多部分HTTP响应来发送回多个图像,但是浏览器支持可能会出现问题(请参阅: 几年后的问题 )。


In your getphoto.php source, you're intending to call MongoGridFS::findOne() with a string parameter. 在您的getphoto.php源代码中,您打算使用字符串参数调用MongoGridFS :: findOne() You should be aware that users could exploit the query string so that $_REQUEST['filename'] is actually an array (see: this post on the subject ). 您应该意识到,用户可以利用查询字符串,因此$_REQUEST['filename']实际上是一个数组(请参阅: 有关此主题的文章 )。 You would do well to check the request parameter and/or cast it to a string before passing it to findOne() . 在将请求参数传递给findOne()之前,您最好检查一下请求参数和/或将其转换为字符串。

Additionally: 另外:

  • This is going to query on the filename field, so you should make sure that it's indexed. 这将在filename段中进行查询,因此您应确保已对其进行索引。
  • Per the fs.files specification , the filename field is optional and not necessarily unique. 根据fs.files 规范filename段是可选的,不一定是唯一的。 It's quite possible that multiple files in GridFS could have the same filename. GridFS中的多个文件很有可能具有相同的文件名。

Considering the above points, it may be easier to just use the 24 hexadecimal characters of the ObjectId as a request parameter, construct a MongoId , and query with that on on the _id field (or use MongoGridFS::get() ). 考虑到以上几点,仅使用ObjectId的24个十六进制字符作为请求参数,构造一个MongoId ,然后在_id字段上对其进行查询(或使用MongoGridFS :: get() )可能会更容易。 My previous points on validating the request parameter would still stand in this case -- it would allow you to use the default _id index. 在这种情况下,我之前验证请求参数的要点仍然有效-它将允许您使用默认的_id索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM