Fillagring är en viktig funktion som krävs i flera processer i olika typer av applikationer. Förekomsten av processer som Content Delivery Networks (CDNs)
, som inrättats genom tredjeparts molnalternativ som Amazon Web Services, och lokala fillagringsalternativ har alltid gjort det lättare att bygga en sådan funktion.
Konceptet att lagra filer direkt i en databas genom ett enda API-samtal har dock fascinerat mig under en längre tid. Det var där GridFS kom in i bilden för mig.
GridFS – A Layman’s Understanding
MongoDB har en drivrutinsspecifikation för att ladda upp och hämta filer från den som kallas GridFS. GridFS gör det möjligt att lagra och hämta filer, även sådana som överskrider BSON-dokumentens storleksgräns på 16 MB.
GridFS tar i princip en fil och delar upp den i flera delar som lagras som enskilda dokument i två samlingar:
-
chunk
samlingenchunk
(lagrar dokumentdelarna) och -
file
samlingenfile
(lagrar de följdriktiga ytterligare metadata).
Varje del är begränsad till 255 KB i storlek. Detta innebär att den sista delen normalt är antingen lika med eller mindre än 255 KB. Det låter ganska snyggt.
När du läser från GridFS återställer drivrutinen alla chunks efter behov. Detta innebär att du kan läsa sektioner av en fil enligt ditt frågeområde. Såsom att lyssna på ett segment av en ljudfil eller hämta ett avsnitt av en videofil.
Anmärkning: Det är att föredra att använda GridFS för att lagra filer som normalt överstiger storleksgränsen på 16 MB. För mindre filer rekommenderas att använda BinData-formatet för att lagra filerna i enskilda dokument.
Detta sammanfattar hur GridFS fungerar i allmänhet. Dags att doppa fötterna i lite fungerande kod och se hur man implementerar ett sådant system.
Enough Talk, Show Me the Code
Vi använder Node.js med tillgång till en molninstans av MongoDB för vår installation. Du kan hitta kodförrådet för exempelprogrammet här.
Vi kommer helt och hållet att fokusera på segment av koden som rör funktionaliteterna i GridFS. Vi kommer att lära oss att konfigurera den och använda den för att lagra filer, hämta filer eller en viss fil och ta bort en viss fil. Låt oss börja då.
Initialisera lagringsmotorn
De paket som behövs för att initialisera motorn är multer-gridfs-storage
och multer
. Vi använder också method-override
middleware för att aktivera raderingsoperationen för filer. Npm-modulen crypto
används för att kryptera filnamnen när de lagras och läses från databasen.
När lagringsmotorn som använder GridFS har initialiserats är det bara att anropa den med hjälp av middleware multer. Den skickas sedan vidare till respektive väg som utför de olika fillagringsoperationerna.
Initialisera GridFS-ström
Vi initialiserar en GridFS-ström enligt koden nedan. Strömmen behövs för att läsa filerna från databasen och även för att hjälpa till att rendera en bild till en webbläsare när det behövs.
Uppladdning av en enskild fil eller bild
Vi återanvänder den uppladdningsmedie vi skapade tidigare.
Notera: Namnet file
används som en parameter i upload.single()
eftersom vi har nyckeln med ett liknande namn som bär filen som skickas från klienten.
Överför flera filer eller bilder
Vi kan också överföra flera filer samtidigt. Istället för upload.single()
måste vi helt enkelt använda upload.multiple(<number of files>)
.
Notera: Antalet filer som laddas upp kan vara mindre än det definierade antalet filer.
Hämta alla filer från databasen
Med hjälp av den initialiserade strömmen kan vi hämta alla filer i den aktuella databasen med gfs.find().toArray(...)
. När filerna är hämtade mappar vi dem till en array och skickar svaret.
Fetch a Single File By Filename
Det är superenkelt att fråga GridFS efter en enskild fil baserat på ett specifikt attribut som filename
. Med hjälp av GridFS-strömmen kan du fråga databasen genom funktionen gfs.find({<add query here>})
.
Rendera en hämtad bild i webbläsaren
Det här är en lite knepigare del eftersom du inte bara måste hämta en fil från databasen utan också rendera den som en bild i respektive webbläsare. Vi hämtar filen normalt. Ingen förändring i den processen.
Därefter kan vi med hjälp av metoden openDownloadStreamByName()
på gfs stream enkelt rendera en bild eftersom den returnerar en läsbar ström. Efter att ha gjort det kan vi använda JavaScript:s pipe()
för att strömma svaret.
Släck en viss fil efter id
Det är lika enkelt att radera en fil. Vi använder stream-metoden delete()
med parametern _id
för att fråga och ta bort den berörda filen.
Dessa är de viktigaste funktionerna som erbjuds av lagringsmotorns design. Jag hade utnyttjat de GridFS-funktioner som diskuterats för att skapa en enkel applikation för uppladdning av bilder. Du kan fördjupa dig i koden i respository.
Slutsats
Det tog mig en del tid och en ordentlig mängd kamp för att förstå hur man kan använda GridFS för ett personligt projekt. På grund av detta ville jag se till att åtminstone en annan person inte behövde investera samma tid.
Med detta sagt skulle jag rekommendera att använda GridFS med försiktighet. Det är inte en silverkula för alla dina problem med fillagring. Ändå är det en smart specifikation att känna till och vara medveten om.