Molte applicazioni implicano la gestione dei file e l'archiviazione dei file è una caratteristica importante per migliorare l'elaborazione dei dati. L'archiviazione dei file richiede spesso una CDN (Content Delivery Network) di terze parti, come i servizi Web di Amazon, ma questo rende il processo di gestione un po' noioso. Sarebbe più facile accedere a tutte le tue risorse da un unico cloud storage, piuttosto che da più risorse, poiché potrebbe esserci la possibilità di un errore durante il recupero.
Memorizzare i file direttamente in un database tramite una singola chiamata API non è stato facile fino all'introduzione di GridFS in MongoDB.
Cos'è MongoDB GridFS
GridFs è un livello di astrazione in MongoDB utilizzato per l'archiviazione e il ripristino di file di grandi dimensioni come video, audio e immagini. Questo file system memorizza file anche più significativi di 16 MB all'interno delle raccolte di dati MongoDB. I file vengono archiviati scomponendoli prima in blocchi di dati più piccoli, ciascuno con una dimensione di 255 KB.
GridFS utilizza due sistemi di raccolta per archiviare i file:
- pezzo :Questa è la raccolta che memorizza le parti del documento. I blocchi sono limitati a una dimensione di 255 KB ciascuno e quando si esegue una query, il driver GridFS riassembla tutti i blocchi secondo l'id univoco di archiviazione. Ad esempio, potresti voler recuperare un segmento di un file video piuttosto che l'intero file, questo è possibile semplicemente interrogando l'intervallo corretto che desideri.
- File :memorizza i conseguenti metadati aggiuntivi per il file.
Le raccolte sono poste in un bucket comune e quindi prefissate ciascuna con il nome del bucket che per impostazione predefinita è fs e quindi abbiamo:
- fs.chunks
- fs.files
Si può scegliere un nome di bucket diverso, ma il nome completo della raccolta è soggetto a:limite di spazio dei nomi di 255 byte.
Raccolta pezzi
I documenti di raccolta dei pezzi hanno il formato:
{
"_id" : <ObjectId>,
"files_id" : <ObjectId>,
"n" : <num>,
"data" : <binary>
}
Dove:
- _id:è l'identificatore univoco per il blocco
- files_id:è l'_id del documento padre archiviato nella raccolta di file
- n:è il numero di sequenza del blocco che inizia con 0.
- dati:è il carico utile del blocco come tipo binario BSON.
Un indice composto che utilizza file_id e n campi viene utilizzato per consentire un recupero efficiente di blocchi, ad esempio:
db.fs.chunks.find( { files_id: fileId } ).sort( { n: 1 } )
Per creare questo indice se non esiste puoi eseguire il seguente comando su una shell mongo:
db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );
Raccolta file
I documenti in questa raccolta prendono la forma
{
"_id" : <ObjectId>,
"length" : <num>,
"chunkSize" : <num>,
"uploadDate" : <timestamp>,
"filename" : <string>,
"metadata" : <any>,
}
Dove:
- _id:è l'identificatore univoco per il documento che è del tipo di dati scelto per il documento originale e per impostazione predefinita in MongoDB è BSON ObjectId.
- lunghezza:è la dimensione del documento in byte
- chunkSize:dimensione di ogni blocco che è limitata a 255 kilobyte
- uploadDate:campo di tipo Data che memorizza la data in cui il documento è stato archiviato per la prima volta.
- nomefile:questo è un campo facoltativo che è un'identificazione leggibile dall'uomo per il file.
- metadata:questo è un campo facoltativo che contiene informazioni aggiuntive che si desidera memorizzare.
Di seguito è mostrato un esempio di file fs.
{
"filename": "file.html",
"chunkSize": NumberInt(23980),
"uploadDate": ISODate("2020-08-11T10:02:15.237Z"),
"length": NumberInt(312)
}
Come la raccolta dei blocchi, nella raccolta dei file viene utilizzato un indice composto che utilizza i campi nomefile e data di caricamento per consentire un recupero efficiente dei file, ad esempio:
db.fs.files.find( { filename: fileName } ).sort( { uploadDate: 1 } )
Per creare questo indice se non esiste puoi eseguire il seguente comando su una shell mongo:
db.fs.file.createIndex( { filename: 1, uploadDate: 1 }, { unique: true } );
Quando utilizzare il sistema di archiviazione GridFS MongoDB
MongoDB GridFS non è comunemente usato, ma le seguenti sono le condizioni che potrebbero richiedere l'uso di questo sistema di archiviazione GridFS;
- Quando il file system corrente ha un limite al numero di file che possono essere archiviati in una determinata directory.
- Quando si intende accedere a parte delle informazioni archiviate, GridFS consente di richiamare parti del file senza accedere all'intero documento.
- Quando si intende distribuire file e relativi metadati tramite set di repliche geograficamente distribuiti, GridFS consente ai metadati di sincronizzare e distribuire automaticamente i dati su più sistemi di destinazione.
Quando non utilizzare il sistema di archiviazione MongoDB GridFS
Il sistema di archiviazione GridFS non è tuttavia appropriato da utilizzare quando sarà necessario aggiornare il contenuto dell'intero file salvato in GridFS.
Come aggiungere file a GridFS
Quando si archivia un file mp3 in MongoDB utilizzando GridF, la procedura corretta da seguire è questa;
- Apri il terminale (il prompt dei comandi)
- Vai a mongofiles.exe (che si trova nella cartella bin)
- Usa il comando
>mongofiles.exe -d gridfs put song.mp3
Dopo il comando, il nome del database da utilizzare è gridfs, se per caso manca il nome MongoDB crea automaticamente un documento che memorizza il file sul database.
Per visualizzare il file memorizzato in GridFS usa il comando query qui sotto sulla mongo shell;
>db.fs.files.find()
Il comando restituisce un documento con il formato mostrato di seguito:
{
_id: ObjectId('526a922bf8b4aa4d33fdf84d'),
filename: "song.mp3",
chunkSize: 233390,
uploadDate: new Date(1397391643474), md5: "e4f53379c909f7bed2e9d631e15c1c41",
length: 10302960
}
Il file ha i seguenti dettagli, nome file, lunghezza, data di caricamento, dimensione del blocco e object_id. I blocchi nella raccolta fs.chunks possono essere visualizzati utilizzando l'id restituito nella query iniziale, come mostrato di seguito.
>db.fs.chunks.find({files_id:ObjectId('526a922bf8b4aa4d33fdf84d')})
Sharding GridFS
Anche il partizionamento orizzontale è un'altra funzionalità applicabile con GridFS. Per eseguire la raccolta di frammenti di frammenti, è possibile utilizzare un indice composto di {file_id:1, n:1} o {file_id:1} come chiave di partizione.
L'Harshed Sharding è possibile solo se i driver MongoDB non eseguono filemd5.
Le raccolte di file spesso non sono partizionate perché contengono solo metadati e sono molto piccole. Le chiavi disponibili non forniscono nemmeno una distribuzione uniforme in un cluster partizionato. Tuttavia, se è necessario partizionare una raccolta di file, è possibile utilizzare il campo _id in combinazione con alcuni campi dell'applicazione.
Limitazioni GridFS
Il file system GridFS ha le seguenti limitazioni:
- Aggiornamento atomico: GridFS non ha un aggiornamento atomico. Ciò semplifica l'aggiornamento manuale selezionando la versione richiesta dei file e mantenendo in esecuzione più versioni dei file
- Prestazioni : il sistema tende a essere lento con il file system e il server web.
- Set di lavoro: uno usa un altro server quando lavora su un nuovo working set. Questo viene fatto in modo da evitare di disturbare il working set in esecuzione.
Conclusione
GridFS è come un proiettile d'argento per gli sviluppatori che intendono archiviare file di grandi dimensioni in MongoDB. Il sistema di archiviazione GridFS offre agli sviluppatori la possibilità di archiviare file di grandi dimensioni e recuperare parti dei file necessari. GridFS è, quindi, un'eccellente funzionalità di MongoDB che può essere utilizzata con varie applicazioni.