Сетки в mongodb

Недавно мы интегрировали Gridfs в mongodb для хранения изображений. По моему требованию, ранее мы использовали NFS для получения или хранения изображений в каталоге. его становится все более медленным для изображений. Итак, мы интегрировали GridFS.

GridFS, но теперь я поясню, как мы можем получить несколько изображений по одному запросу и показать их в браузере? Потому что мы заполнили около 1 л фотографий в шардинге mongodb gridfs. Но я не могу получить более одного изображения по одному запросу.

Пример кода приведен ниже. - Следующий код вернет только одну фотографию. Я не могу получить все изображения по одному запросу. Если кто-то сталкивается с такими проблемами, пожалуйста, поделитесь с нами.

Метод 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);
        }
}

Метод 2: он возвращает все изображения, но, как и в NFS, каждое изображение будет получать каждый HTTP-запрос. Нет сохранения.

$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:

$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);

person Saikumar    schedule 15.06.2013    source источник


Ответы (1)


Я не понимаю, как вы могли бы вернуть несколько файлов в одном запросе, если бы вы не использовали один из PHP сжатие и расширение архива, чтобы объединить их в один файл, который, в свою очередь, был ретранслирован как HTTP-ответ.

Если изображения небольшие, можно встроить их в HTML как кодированные в base64 URI данных. Этот метод часто используется для встраивания небольших изображений (размер значка) в значения CSS background-image; однако он не подходит для больших изображений, так как накладные расходы на хранение довольно высоки.


Относительно этого запроса в вашем первом примере кода:

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

Я понимаю, что эта строка была закомментирована, но если вы выполняете такой запрос, я бы предложил индексировать metadata.memberid, чтобы избежать сканирования каждого документа в коллекции fs.files.

Итерация, которую вы выполняли, пытается последовательно распечатать заголовок типа содержимого и байтовое содержимое несколько изображений JPG. Функция PHP header() не может вызываться таким образом несколько раз.

Вы можете использовать составные HTTP-ответы для отправки нескольких изображений, но поддержка браузера может быть проблематичной (см.: этот вопрос, заданный несколько лет назад).


В исходном коде getphoto.php вы собираетесь вызвать MongoGridFS::findOne() со строковым параметром. Вы должны знать, что пользователи могут использовать строку запроса так, что $_REQUEST['filename'] на самом деле является массивом (см.: этот пост на эту тему ). Было бы неплохо проверить параметр запроса и/или преобразовать его в строку перед передачей в findOne().

Кроме того:

  • Это будет запрос в поле filename, поэтому вы должны убедиться, что оно проиндексировано.
  • Согласно fs.files спецификации, поле filename является необязательным и не обязательно уникальный. Вполне возможно, что несколько файлов в GridFS могут иметь одинаковое имя файла.

Учитывая вышеизложенное, может быть проще просто использовать 24 шестнадцатеричных символа ObjectId в качестве параметра запроса, создать ссылку MongoId и запросите его в поле _id (или используйте MongoGridFS::get()). Мои предыдущие замечания по проверке параметра запроса останутся в силе и в этом случае — это позволит вам использовать индекс _id по умолчанию.

person jmikola    schedule 27.06.2013