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.

Objektmappning mellan nod och MongoDB hanteras via Mongoose

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:

NoSQL-dokument vs., Relationstabeller i SQL

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

  1. ladda ner lämplig MongoDB-version för ditt operativsystem från MongoDB-webbplatsen och följ deras installationsanvisningar
  2. skapa en gratis sandboxdatabasabonnemang på mlab
  3. 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.

modul import/kräver arbetsflöde

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

  1. _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.
  2. värdet för fältetemail returneras., Observera att det är lägre cased eftersom vi angav attributet lowercase:true I schemat.
  3. __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:

  1. typ av händelse (’init’, ’validera’, ’spara’, ’ta bort’)
  2. en återuppringning som utförs med detta refererar till modellinstansen
exempel på mellanprogram (Alias., före och efter krokar)

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:

  1. hitta alla användare
  2. hoppa över de första 100 posterna
  3. begränsa resultaten till 10 poster
  4. sortera resultaten av fältet Förnamn
  5. Välj förstnamnet
  6. 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.

om den här artikeln var till hjälp ??? och följ mig på Twitter.

du kanske också gillar min workshop på youtube: Hur man bygger en REST API med Node | Express | Mongo