Docs Menu
Docs Home
/ /

Almacene archivos grandes

En esta guía, aprenderá a almacenar y recuperar archivos grandes en MongoDB usando GridFS. GridFS es una especificación implementada por la biblioteca PHP de MongoDB que describe cómo dividir archivos en fragmentos al almacenarlos y reensamblarlos al recuperarlos. La implementación de GridFS en la biblioteca es una abstracción que gestiona las operaciones y la organización del almacenamiento de archivos.

Utilice GridFS si el tamaño de sus archivos supera el límite de tamaño de documento BSON de 16MB. Para obtener información más detallada sobre si GridFS es adecuado para su caso de uso, consulte GridFS en el manual del servidor MongoDB.

GridFS organiza los archivos en un bucket, un grupo de colecciones de MongoDB que contiene los fragmentos de archivos y la información que los describe. El bucket contiene las siguientes colecciones, nombradas según la convención definida en la especificación de GridFS:

  • El chunks La colección almacena los fragmentos de archivos binarios.

  • La colección files almacena los metadatos del archivo.

Al crear un nuevo bucket de GridFS, la biblioteca crea las colecciones anteriores, con el nombre de bucket predeterminado como fs prefijo, a menos que se especifique otro. La biblioteca también crea un índice en cada colección para garantizar la recuperación eficiente de los archivos y los metadatos relacionados. Si el bucket de GridFS no existe, la biblioteca lo crea solo cuando se realiza la primera operación de escritura. La biblioteca crea índices solo si no existen y cuando el bucket está vacío. Para obtener más información sobre los índices de GridFS, consulte Índices de GridFS en el manual de MongoDB Server.

Al usar GridFS para almacenar archivos, la biblioteca los divide en fragmentos más pequeños, cada uno representado por un documento independiente en la chunks colección. También crea un documento en la files colección que contiene el ID, el nombre y otros metadatos del archivo. Puede cargar el archivo pasando un flujo a la biblioteca PHP de MongoDB para su consumo o creando un nuevo flujo y escribiendo en él directamente. Para obtener más información sobre los flujos, consulte Flujos. en el manual de PHP.

Vea el siguiente diagrama para ver cómo GridFS divide los archivos cuando se cargan en un depósito:

Un diagrama que muestra cómo GridFS sube un archivo a un bucket

Al recuperar archivos, GridFS obtiene los metadatos de la colección files en el contenedor especificado y utiliza la información para reconstruir el archivo a partir de los documentos de la colección chunks. Puede leer el archivo escribiendo su contenido en una secuencia existente o creando una nueva que apunte al archivo.

Para almacenar o recuperar archivos de GridFS, llame al método MongoDB\Database::selectGridFSBucket() en su base de datos. Este método accede a un contenedor existente o crea uno nuevo si no existe.

El siguiente ejemplo llama al método selectGridFSBucket() en la base de datos db:

$bucket = $client->db->selectGridFSBucket();

Puede personalizar la configuración del bucket de GridFS pasando una matriz que especifique los valores de las opciones al método selectGridFSBucket(). La siguiente tabla describe algunas opciones que puede configurar en la matriz:

Opción
Descripción

bucketName

Specifies the bucket name to use as a prefix for the files and chunks collections. The default value is 'fs'.
Type: string

chunkSizeBytes

Specifies the chunk size that GridFS splits files into. The default value is 261120.
Type: integer

readConcern

Specifies the read concern to use for bucket operations. The default value is the database's read concern.
Type: MongoDB\Driver\ReadConcern

readPreference

Specifies the read preference to use for bucket operations. The default value is the database's read preference.
Type: MongoDB\Driver\ReadPreference

writeConcern

Specifies the write concern to use for bucket operations. The default value is the database's write concern.
Type: MongoDB\Driver\WriteConcern

El siguiente ejemplo crea un depósito llamado 'myCustomBucket' pasando una matriz a selectGridFSBucket() que establece la opción bucketName:

$customBucket = $client->db->selectGridFSBucket(
['bucketName' => 'myCustomBucket'],
);

Puede cargar archivos a un depósito GridFS mediante los siguientes métodos:

  • MongoDB\GridFS\Bucket::openUploadStream(): Abre un nuevo flujo de carga al que se pueden guardar los contenidos del archivo

  • MongoDB\GridFS\Bucket::uploadFromStream(): Carga el contenido de una transmisión existente a un archivo GridFS

Utilice el método openUploadStream() para crear un flujo de carga para un nombre de archivo determinado. El método openUploadStream() permite especificar información de configuración en una matriz de opciones, que puede pasar como parámetro.

Este ejemplo utiliza un flujo de carga para realizar las siguientes acciones:

  • Abre una secuencia escribible para un nuevo archivo GridFS llamado 'my_file'

  • Establece la opción metadata en un parámetro de matriz en el método openUploadStream()

  • Llama al método fwrite() para escribir datos en 'my_file', al que apunta la secuencia

  • Llama al método fclose() para cerrar la secuencia que apunta a 'my_file'

$stream = $bucket->openUploadStream('my_file', [
'metadata' => ['contentType' => 'text/plain'],
]);
fwrite($stream, 'Data to store');
fclose($stream);

Utilice el método uploadFromStream() para cargar el contenido de una secuencia a un nuevo archivo GridFS. El método uploadFromStream() permite especificar información de configuración en una matriz de opciones, que puede pasar como parámetro.

Este ejemplo realiza las siguientes acciones:

  • Llama al método fopen() para abrir un archivo ubicado en /path/to/input_file como una secuencia en modo de lectura binaria (rb)

  • Llama al método uploadFromStream() para cargar el contenido de la transmisión a un archivo GridFS llamado 'new_file'

$file = fopen('/path/to/input_file', 'rb');
$bucket->uploadFromStream('new_file', $file);

En esta sección, puedes aprender a recuperar metadatos de archivos almacenados en la colección files del depósito de GridFS. Los metadatos contienen información sobre el archivo al que se refieren, incluyendo:

  • El _id del archivo

  • El nombre del archivo

  • La longitud/tamaño del archivo

  • La fecha y hora de carga

  • Un documento metadata en el que puedes almacenar cualquier otra información

Para recuperar archivos de un bucket de GridFS, llame al método MongoDB\GridFS\Bucket::find() en la instancia MongoDB\GridFS\Bucket. El método devuelve una instancia MongoDB\Driver\Cursor desde la que puede acceder a los resultados. Para obtener más información sobre los objetos Cursor en la biblioteca PHP de MongoDB, consulte Guíade acceso a datos desde un cursor.

El siguiente ejemplo de código muestra cómo recuperar e imprimir metadatos de archivos en un bucket de GridFS. Utiliza un bucle foreach para iterar sobre el cursor devuelto y mostrar el contenido de los archivos cargados en los ejemplos de Cargar Archivos:

$files = $bucket->find();
foreach ($files as $fileDocument) {
echo toJSON($fileDocument), PHP_EOL;
}
{ "_id" : { "$oid" : "..." }, "chunkSize" : 261120, "filename" : "my_file",
"length" : 13, "uploadDate" : { ... }, "metadata" : {
"contentType" : "text/plain" } }
{ "_id" : { "$oid" : "..." }, "chunkSize" : 261120, "filename" : "new_file",
"length" : 13, "uploadDate" : { ... } }

El find() método acepta varias especificaciones de consulta. Puede usar su $options parámetro para especificar el orden de clasificación, el número máximo de documentos a devolver y el número de documentos que se omitirán antes de devolver. Para ver una lista de las opciones disponibles, consulte la documentación de la API.

Nota

El ejemplo anterior llama al método toJSON() para imprimir metadatos del archivo como JSON extendido, definido en el siguiente código:

function toJSON(object $document): string
{
return MongoDB\BSON\Document::fromPHP($document)->toRelaxedExtendedJSON();
}

Puede descargar archivos de un depósito GridFS mediante los siguientes métodos:

  • MongoDB\GridFS\Bucket::openDownloadStreamByName() o MongoDB\GridFS\Bucket::openDownloadStream(): abre una nueva secuencia de descarga desde la que puede leer el contenido del archivo

  • MongoDB\GridFS\Bucket::downloadToStream(): Escribe el archivo completo en un flujo de descarga existente

Puede descargar archivos de su base de datos MongoDB utilizando el método MongoDB\GridFS\Bucket::openDownloadStreamByName() para crear un flujo de descarga.

Este ejemplo utiliza un flujo de descarga para realizar las siguientes acciones:

  • Selecciona un archivo GridFS llamado,'my_file' cargado en el ejemplo Escribir en un flujo de carga, y lo abre como un flujo legible

  • Llama al método stream_get_contents() para leer el contenido de 'my_file'

  • Imprime el contenido del archivo

  • Llama al método fclose() para cerrar el flujo de descarga que apunta a 'my_file'

$stream = $bucket->openDownloadStreamByName('my_file');
$contents = stream_get_contents($stream);
echo $contents, PHP_EOL;
fclose($stream);
"Data to store"

Nota

Si hay varios documentos con el mismo nombre de archivo, GridFS transmitirá el archivo más reciente con el nombre dado (según lo determinado por el campo uploadDate).

Alternativamente, puede utilizar el método MongoDB\GridFS\Bucket::openDownloadStream(), que toma el campo _id de un archivo como parámetro:

$stream = $bucket->openDownloadStream(new ObjectId('66e0a5487c880f844c0a32b1'));
$contents = stream_get_contents($stream);
fclose($stream);

Nota

La API de streaming de GridFS no puede cargar fragmentos parciales. Cuando un flujo de descarga necesita extraer un fragmento de MongoDB, lo extrae completo a memoria.255El tamaño predeterminado de fragmento de kilobytes suele ser suficiente, pero puede reducirlo para reducir la sobrecarga de memoria o aumentarlo al trabajar con archivos más grandes. Para obtener más información sobre cómo configurar el tamaño de fragmento, consulte la sección "Personalizar el contenedor" de esta página.

Cuando su bucket contiene varios archivos con el mismo nombre, GridFS selecciona la versión más reciente del archivo de forma predeterminada. Para diferenciar cada archivo con el mismo nombre, GridFS les asigna un número de revisión, ordenado por fecha de carga.

El número de revisión del archivo original es 0 y el siguiente número de revisión más reciente es 1. También puede especificar valores negativos que correspondan a la fecha de la revisión. El valor de revisión -1 hace referencia a la revisión más reciente y -2 a la siguiente.

Puede indicar a GridFS que descargue una revisión de archivo específica pasando una matriz de opciones al método openDownloadStreamByName() y especificando la opción revision. El siguiente ejemplo lee el contenido del archivo original llamado 'my_file' en lugar de la revisión más reciente:

$stream = $bucket->openDownloadStreamByName('my_file', ['revision' => 0]);
$contents = stream_get_contents($stream);
fclose($stream);

Puede descargar el contenido de un archivo GridFS a una transmisión existente llamando al método MongoDB\GridFS\Bucket::downloadToStream() en su bucket.

Este ejemplo realiza las siguientes acciones:

  • Llama al método fopen() para abrir un archivo ubicado en /path/to/output_file como una secuencia en modo de escritura binaria (wb)

  • Descarga un archivo GridFS que tiene un valor _id de ObjectId('66e0a5487c880f844c0a32b1') en la transmisión

$file = fopen('/path/to/output_file', 'wb');
$bucket->downloadToStream(
new ObjectId('66e0a5487c880f844c0a32b1'),
$file,
);

Utilice el método MongoDB\GridFS\Bucket::rename() para actualizar el nombre de un archivo GridFS en su bucket. Pase los siguientes parámetros al método rename():

  • _id valor del archivo que desea renombrar

  • Nuevo nombre de archivo

El siguiente ejemplo muestra cómo actualizar el campo filename a 'new_file_name' haciendo referencia al valor _id de un archivo:

$bucket->rename(new ObjectId('66e0a5487c880f844c0a32b1'), 'new_file_name');

Como alternativa, puede usar el método MongoDB\GridFS\Bucket::renameByName() para renombrar un archivo GridFS y todas sus revisiones. Pase los siguientes parámetros al método renameByName():

  • filename valor que desea cambiar

  • Nuevo nombre de archivo

El siguiente ejemplo cambia el nombre de todos los archivos que tienen un valor filename de 'my_file':

$bucket->renameByName('my_file', 'new_file_name');

Utilice el método MongoDB\GridFS\Bucket::delete() para eliminar el documento de colección de un archivo GridFS y los fragmentos asociados de su bucket. Esto elimina el archivo. Pase el valor _id del archivo que desea eliminar como parámetro al método delete().

El siguiente ejemplo le muestra cómo eliminar un archivo haciendo referencia a su campo _id:

$bucket->delete(new ObjectId('66e0a5487c880f844c0a32b1'));

Como alternativa, puede usar el método MongoDB\GridFS\Bucket::deleteByName() para eliminar un archivo GridFS y todas sus revisiones. Pase el valor filename del archivo que desea eliminar como parámetro al método deleteByName(), como se muestra en el siguiente código:

$bucket->deleteByName('my_file');

Para obtener más información sobre el uso de la biblioteca PHP MongoDB para almacenar y recuperar archivos grandes, consulte la siguiente documentación de API:

Volver

Configurar las operaciones CRUD

En esta página