av Nick Karnik
Mongoose är ett Objektdatamodelleringsbibliotek (ODM) för MongoDB och Nod.js. Det hanterar relationer mellan data, ger schema validering, och används för att översätta mellan objekt i kod och representation av dessa objekt i MongoDB.
MongoDB är ett schema-mindre NoSQL dokumentdatabas., Det innebär att du kan lagra JSON-dokument i det, och strukturen för dessa dokument kan variera eftersom det inte verkställs som SQL-databaser. Detta är en av fördelarna med att använda NoSQL eftersom det påskyndar applikationsutvecklingen och minskar komplexiteten i distributioner.
nedan är ett exempel på hur data lagras i Mongo vs SQL-databas:
terminologier
Samlingar
’samlingar’ i Mongo motsvarar tabeller i relationsdatabaser. De kan hålla flera JSON-dokument.
dokument
”dokument” motsvarar poster eller rader av data i SQL. Medan en SQL-rad kan referera till data i andra tabeller, kombinerar Mongo-dokument vanligtvis det i ett dokument.
fält
fält eller attribut liknar kolumner i en SQL-tabell.
Schema
medan Mongo är schema-mindre definierar SQL ett schema via tabelldefinitionen., En Mongoose ’schema’ är en dokumentdatastruktur (eller form av dokumentet) som verkställs via applikationsskiktet.
modeller
’modeller’ är konstruktörer med högre order som tar ett schema och skapar en instans av ett dokument som motsvarar poster i en relationsdatabas.
komma igång
Mongo Installation
innan vi börjar, låt oss ställa Mongo., Du kan välja mellan ett av följande alternativ (vi använder alternativ #1 för den här artikeln):
- ladda ner lämplig MongoDB-version för ditt operativsystem från MongoDB-webbplatsen och följ deras installationsanvisningar
- skapa en gratis sandboxdatabasabonnemang på mlab
- installera Mongo med Docker om du föredrar att använda docker
låt oss navigera genom några av grunderna i Mongoose genom att implementera en modell som representerar data för en förenklad adressbok.
Jag använder Visual Studio Code, Node 8.9 och NPM 5.6., Brand upp din favorit IDE, skapa ett tomt projekt, och låt oss komma igång! Vi kommer att använda den begränsade ES6-syntaxen i noden, så vi kommer inte att konfigurera Babel.
NPM Install
låt oss gå till projektmappen och initiera vårt projekt
npm init -y
låt oss installera Mongoose och ett valideringsbibliotek med följande kommando:
npm install mongoose validator
ovanstående installationskommando installerar den senaste versionen av biblioteken. Den Mongoose syntax i denna artikel är specifik för Mongoose V5 och därefter.,
databasanslutning
skapa en fil./src/database.js
under projektroten.
därefter lägger vi till en enkel klass med en metod som ansluter till databasen.
din anslutningssträng varierar beroende på din installation.
require(‘mongoose’)
anrop ovan returnerar ett Singleton-objekt. Det betyder att första gången du ringer require(‘mongoose’)
skapar det en instans av Mungoklassen och returnerar den., Vid efterföljande samtal kommer det att returnera samma instans som skapades och returnerades till dig första gången på grund av hur modulimport/export fungerar i ES6.
På samma sätt har vi gjort vår databasklass till en singleton genom att returnera en instans av klassen imodule.exports
eftersom vi bara behöver en enda anslutning till databasen.,
ES6 gör det väldigt enkelt för oss att skapa ett Singleton (single instance) – mönster på grund av hur modul loader fungerar genom att cacha svaret från en tidigare importerad fil.
Mongoose Schema vs Modell
en Mongoose modell är ett omslag på Mongoose schemat. Ett Mongoosschema definierar dokumentets struktur, standardvärden, validerare etc., medan en Mungo modell ger ett gränssnitt till databasen för att skapa, fråga, uppdatera, ta bort poster, etc.
skapa en Mungo modell består främst av tre delar:
1., Referera Mongoose
let mongoose = require('mongoose')
denna referens kommer att vara densamma som den som returnerades när vi anslutit till databasen, vilket innebär att schemat och modelldefinitionerna inte behöver uttryckligen ansluta till databasen.
2. Definiera schemat
ett schema definierar dokumentegenskaper genom ett objekt där nyckelnamnet motsvarar egenskapsnamnet i samlingen.,
let emailSchema = new mongoose.Schema({ email: String})
här definierar vi en egenskap som kallas e-post med en Schematypsträng som kartlägger till en intern validator som kommer att utlösas när modellen sparas i databasen. Det kommer att misslyckas om datatypen för värdet inte är en strängtyp.
följande Schematyper är tillåtna:
- Array
- Boolean
- buffert
- datum
- blandad (en generisk/flexibel datatyp)
- nummer
- Objektid
- String
blandad och Objektid definieras underrequire(‘mongoose’).Schema.Types
.
3., Exportera en modell
Vi måste ringa modellkonstruktören på Mongoose-instansen och skicka det namnet på samlingen och en hänvisning till schemadefinitionen.
module.exports = mongoose.model('Email', emailSchema)
låt oss kombinera ovanstående kod till./src/models/email.js
för att definiera innehållet i en grundläggande e-postmodell:
en schemadefinition ska vara enkel, men dess komplexitet baseras vanligtvis på applikationskrav. Scheman kan återanvändas och de kan också innehålla flera barnscheman. I exemplet ovan är värdet på e-postegenskapen en enkel värdetyp., Det kan dock också vara en objekttyp med ytterligare egenskaper på den.
vi kan skapa en instans av den modell vi definierade ovan och fylla den med följande syntax:
let EmailModel = require('./email')let msg = new EmailModel({ email: '[email protected]'})
låt oss förbättra E-postschemat för att göra e-postegenskapen ett unikt, obligatoriskt fält och konvertera värdet till gemener innan du sparar det. Vi kan också lägga till en valideringsfunktion som säkerställer att värdet är en giltig e-postadress. Vi kommer att referera och använda validatorbiblioteket installerat tidigare.,
grundläggande operationer
Mongoose har ett flexibelt API och ger många sätt att utföra en uppgift. Vi kommer inte att fokusera på variationerna eftersom det inte är möjligt för den här artikeln, men kom ihåg att de flesta operationerna kan göras på mer än ett sätt antingen syntaktiskt eller via applikationsarkitekturen.,
skapa post
låt oss skapa en instans av e-postmodellen och spara den i databasen:
resultatet är ett dokument som returneras vid en lyckad räddning:
{ _id: 5a78fe3e2f44ba8f85a2409a, email: '[email protected]', __v: 0 }
följande fält returneras (interna fält är prefixerade med ett understreck):
-
_id
fältet är auto-genererade av Mongo och är en primär nyckel i samlingen. Dess värde är en unik identifierare för dokumentet. - värdet för fältet
email
returneras., Observera att det är lägre cased eftersom vi angav attributetlowercase:true
I schemat. -
__v
är versionKey-egenskapen inställd på varje dokument när den först skapades av Mongoose. Dess värde innehåller den interna översynen av dokumentet.
om du försöker upprepa åtgärden spara ovan får du ett fel eftersom vi har angett att e-postfältet ska vara unikt.
hämta post
låt oss försöka hämta posten som vi sparade i databasen tidigare., Modellklassen exponerar flera statiska och instansmetoder för att utföra operationer på databasen. Vi kommer nu att försöka hitta den post som vi skapade tidigare med hjälp av sökmetoden och skicka e-postmeddelandet som söktermen.
EmailModel .find({ email: '[email protected]' // search query }) .then(doc => { console.log(doc) }) .catch(err => { console.error(err) })
det returnerade dokumentet liknar det som visades när vi skapade posten:
{ _id: 5a78fe3e2f44ba8f85a2409a, email: '[email protected]', __v: 0 }
uppdatera post
låt oss ändra posten ovan genom att ändra e-postadressen och lägga till ett annat fält till den, allt i en enda operation., Av prestandaskäl kommer Mongoose inte att returnera det uppdaterade dokumentet så vi måste skicka en ytterligare parameter för att be om det:
det returnerade dokumentet innehåller det uppdaterade e-postmeddelandet:
{ _id: 5a78fe3e2f44ba8f85a2409a, email: '[email protected]', __v: 0 }
Radera post
Vi kommer att använda findOneAndRemove
– samtalet för att radera en post., Det returnerar det ursprungliga dokumentet som togs bort:
hjälpare
Vi har tittat på några av de grundläggande funktionerna ovan kallas CRUD (skapa, läsa, uppdatera, ta bort) operationer, men Mongoose ger också möjlighet att konfigurera flera typer av hjälpmetoder och egenskaper. Dessa kan användas för att ytterligare förenkla arbetet med data.
låt oss skapa ett användarschema i ./src/models/user.js
med fältenfirstName
och lastName
:
virtuell egendom
en virtuell egendom finns inte kvar i databasen., Vi kan lägga till det i vårt schema som hjälpare för att få och ställa in värden.
låt oss skapa en virtuell egenskap som heterfullName
som kan användas för att ställa in värden påfirstName
ochlastName
och hämta dem som ett kombinerat värde när du läser:
Callbacks för get och set måste använda funktionssordet eftersom vi behöver komma åt modellen viathis
nyckelord. Använda fat arrow funktioner kommer att ändra vadthis
hänvisar till.,
Nu kan vi ställa in firstName
och lastName
genom att tilldela ett värde till fullName
:
koden ovan kommer att mata ut följande:
{ _id: 5a7a4248550ebb9fafd898cf, firstName: 'Thomas', lastName: 'Anderson' } Thomas Anderson
Instansmetoder
vi kan skapa anpassade hjälpmetoder på schemat och få tillgång till dem via modellinstansen. Dessa metoder kommer att ha tillgång till modellobjektet och de kan användas ganska kreativt. Till exempel kan vi skapa en metod för att hitta alla personer som har samma förnamn som den aktuella instansen.,
i det här exemplet, låt oss skapa en funktion för att returnera initialerna för den aktuella användaren. Låt oss lägga till en anpassad hjälpmetod som heter getInitials
I schemat:
userSchema.methods.getInitials = function() { return this.firstName + this.lastName}
den här metoden kommer att vara tillgänglig via en modellinstans:
statiska metoder
i likhet med instansmetoder kan vi skapa statiska metoder på schemat., Låt oss skapa en metod för att hämta alla användare i databasen:
ringa getUsers
på modellklassen kommer att returnera alla användare i databasen:
UserModel.getUsers() .then(docs => { console.log(docs) }) .catch(err => { console.error(err) })
lägga instans och statiska metoder är ett bra sätt att implementera ett gränssnitt för databasinteraktioner på samlingar och poster.
Middleware
Middleware är funktioner som körs i specifika steg i en rörledning., Mongoose stöder middleware för följande operationer:
- Aggregate
- Document
- Model
- Query
till exempel har modeller pre
och post
funktioner som tar två parametrar:
- typ av händelse (’init’, ’validera’, ’spara’, ’ta bort’)
- en återuppringning som utförs med detta refererar till modellinstansen
låt oss prova ett exempel genom att lägga till två fält som heter createdAt
och updatedAt
I vårt schema:
När model.save()
anropas finns det en pre(‘save’, …)
och post(‘save’, …)
händelse som utlöses. För den andra parametern kan du skicka en funktion som anropas när händelsen utlöses. Dessa funktioner tar en parameter till nästa funktion i mellankedjan.,
låt oss lägga till en pre-save hook och ställa in värden för createdAt
och updatedAt
:
låt oss skapa och spara vår modell:
Du bör se värden för createdAt
och updatedAt
när posten som skapas är printed:
plugins
Antag att vi vill spåra när en post skapades och senast uppdaterades på varje samling i vår databas. I stället för att upprepa ovanstående process kan vi skapa ett plugin och tillämpa det på varje schema.,
låt oss skapa en fil ./src/model/plugins/timestamp.js
och replikera ovanstående funktioner som en återanvändbar modul:
för att använda denna plugin, skickar vi det helt enkelt till de scheman som ska ges denna funktionalitet:
Query Building
Mongoose har ett mycket rikt API som hanterar många komplexa operationer som stöds av MongoDB. Tänk på en fråga där vi stegvis kan bygga frågekomponenter.,
i det här exemplet kommer vi att:
- hitta alla användare
- hoppa över de första 100 posterna
- begränsa resultaten till 10 poster
- sortera resultaten av fältet Förnamn
- Välj förstnamnet
- kör den frågan
stänga
Vi har knappt repat ytan utforska några av funktionerna i den här versionen.Mungo. Det är ett rikt bibliotek fullt av användbara och kraftfulla funktioner som gör det till en glädje att arbeta med datamodeller i applikationsskiktet.,
medan du kan interagera med Mongo direkt med Mongo Driver, kommer Mongoose förenkla denna interaktion genom att låta dig modellera relationer mellan data och validera dem enkelt.
roligt faktum: Mongoose är skapad av Valeri Karpov som är en otroligt begåvad ingenjör! Han myntade termen MEAN Stack.