Bruke JOINs I MongoDB NoSQL Databaser

 Bruke $lookUp Med NoSQL

Takk Til Julian Motz for å hjelpe til med å gjennomgå denne artikkelen.

EN av de største forskjellene MELLOM SQL-og NoSQL-databaser ER JOIN. I relasjonsdatabaser LAR SQL JOIN-klausulen deg kombinere rader fra to eller flere tabeller ved hjelp av et felles felt mellom dem. Hvis du for eksempel har tabeller med books og publishers, kan DU skrive SQL-kommandoer som:

SELECT book.title, publisher.nameFROM bookLEFT JOIN book.publisher_id ON publisher.id;

med andre ord har book – tabellen et publisher_id – felt som refererer til id – feltet i publisher – tabellen.

dette er praktisk, siden en enkelt utgiver kunne tilby tusenvis av bøker. Hvis vi noen gang trenger å oppdatere en utgivers detaljer, kan vi endre en enkelt post. Data redundans er minimert, siden vi ikke trenger å gjenta utgiverinformasjonen for hver bok. Teknikken er kjent som normalisering.

SQL databaser tilbyr en rekke normalisering og begrensning funksjoner for å sikre relasjoner opprettholdes.

NoSQL = = INGEN SAMMENFØYNING?

Ikke alltid …

Dokumentorienterte databaser som MongoDB er laget for å lagre denormaliserte data. Ideelt sett bør det ikke være noe forhold mellom samlinger. Hvis de samme dataene kreves i to eller flere dokumenter, må det gjentas.

Dette kan være frustrerende, siden det er få situasjoner der du aldri trenger relasjonsdata. Heldigvis Introduserer MongoDB 3.2 en ny $lookup operatør som kan utføre EN VENSTRE-YTRE-JOIN – lignende operasjon på to eller flere samlinger. Men det er en fangst …

MongoDB Aggregering

$lookup er bare tillatt i aggregeringsoperasjoner. Tenk på disse som en rørledning av operatører som spør, filtrerer og grupperer et resultat. Utgangen fra en operatør brukes som inngang for den neste.

Aggregering er vanskeligere å forstå enn enklere find spørringer og vil vanligvis kjøre tregere. Imidlertid er de kraftige og et uvurderlig alternativ for komplekse søkoperasjoner.

Aggregering er best forklart med et eksempel. Anta at vi lager en sosial medieplattform med en user samling. Den lagrer hver brukers detaljer i separate dokumenter. For eksempel:

{ "_id": ObjectID("45b83bda421238c76f5c1969"), "name": "User One", "email: "[email protected]", "country": "UK", "dob": ISODate("1999-09-13T00:00:00.000Z")}

Vi kan legge til så mange felt som nødvendig, men Alle MongoDB-dokumenter krever et _id – felt som har en unik verdi. _id ligner PÅ EN SQL – primærnøkkel, og vil bli satt inn automatisk om nødvendig.

vårt sosiale nettverk krever nå en post samling, som lagrer mange innsiktsfulle oppdateringer fra brukere. Dokumentene lagrer tekst, dato, en vurdering og en referanse til brukeren som skrev den i et user_id – felt:

{ "_id": ObjectID("17c9812acff9ac0bba018cc1"), "user_id": ObjectID("45b83bda421238c76f5c1969"), "date: ISODate("2016-09-05T03:05:00.123Z"), "text": "My life story so far", "rating": "important"}

Vi vil nå vise de siste tjue innleggene med en» viktig » vurdering fra alle brukere i omvendt kronologisk rekkefølge. Hvert returnerte dokument skal inneholde teksten, tidspunktet for innlegget og den tilhørende brukerens navn og land.

MongoDB-aggregatspørringen sendes en rekke rørledningsoperatører som definerer hver operasjon i rekkefølge. Først må vi trekke ut alle dokumenter fra samlingen post som har riktig vurdering ved hjelp av filteret $match :

{ "$match": { "rating": "important" } }

Vi må nå sortere de samsvarende elementene i omvendt datorekkefølge ved hjelp av operatøren $sort :

{ "$sort": { "date": -1 } }

Siden vi bare krever tjue innlegg, kan vi bruke et $limit stadium, Så MongoDB trenger bare å behandle data vi vil ha:

{ "$limit": 20 }

Vi kan nå bli med data fra user – samlingen ved hjelp av den nye $lookup – operatøren. Det krever et objekt med fire parametere:

  • localField: oppslagsfeltet i inndatadokumentet
  • from: samlingen for å bli med
  • foreignField: feltet som skal slås opp i samlingen from
  • as: navnet på utdatafeltet.

vår operatør er derfor:

{ "$lookup": { "localField": "user_id", "from": "user", "foreignField": "_id", "as": "userinfo"} }

dette vil skape et nytt felt i vår produksjon kalt userinfo. Den inneholder en matrise hvor hver verdi samsvarer med user – dokumentet:

"userinfo": 

Vi har et en-til-en-forhold mellom post.user_id og user._id, siden et innlegg bare kan ha en forfatter. Derfor vil vår userinfo matrise bare inneholde ett element. Vi kan bruke operatøren $unwind til å dekonstruere den til et underdokument:

{ "$unwind": "$userinfo" }

utgangen vil nå bli konvertert til et mer praktisk format som kan ha flere operatører brukt:

"userinfo": { "name": "User One", "email: "[email protected]", …}

Til Slutt kan vi returnere teksten, tidspunktet for innlegget, brukerens navn og land ved hjelp av et $project stadium i rørledningen:

{ "$project": { "text": 1, "date": 1, "userinfo.name": 1, "userinfo.country": 1} }

Setter Alt Sammen

vår endelige aggregerte spørring samsvarer med innlegg, sorterer i rekkefølge, grenser til de siste tjue elementene, knytter sammen brukerdata, flater brukerarrayen og returnerer bare nødvendige felt. Den fulle kommandoen:

db.post.aggregate();

resultatet er en samling på opptil tjue dokumenter. Eksempelvis:

Flott! Jeg Kan Endelig Bytte Til NoSQL!

MongoDB $lookup er nyttig og kraftig, men selv dette grunnleggende eksemplet krever en kompleks aggregatspørring. Det er ikke en erstatning for den kraftigere JOIN-klausulen som tilbys I SQL. MongoDB tilbyr heller ikke begrensninger; hvis et user – dokument slettes, vil orphan post – dokumenter forbli.

Ideelt sett bør operatøren $lookup kreves sjelden. Hvis du trenger det mye, bruker du muligens feil datalager …

hvis du har relasjonsdata, bruk EN RELASJONSDATABASE (SQL)!

når det er sagt, $lookup er et velkomment tillegg Til MongoDB 3.2. Det kan overvinne noen av de mer frustrerende problemene når du bruker små mengder relasjonsdata i En nosql-database.

You might also like

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.