Introduksjon til MongoDBs $lookup-funksjon
MongoDB er en anerkjent NoSQL-database som organiserer data i samlinger. Disse samlingene består av dokumenter, som lagrer informasjon i JSON-format. Man kan tenke på dokumenter som rader i en tradisjonell SQL-database, og samlinger som tabeller.
En sentral del av databasedriften er evnen til å hente ut og analysere data. Dette gir mulighet for å generere rapporter og integrere informasjon fra ulike kilder.
For effektiv datahåndtering kreves det ofte å kombinere informasjon fra flere tabeller i SQL-databaser, eller fra ulike samlinger i NoSQL-miljøer. Dette skaper et mer omfattende datasett.
I MongoDB oppnås denne funksjonaliteten gjennom $lookup
, som tillater å sammenføye data fra to samlinger. Denne prosessen ligner på en venstre ytre sammenføyning i en SQL-database.
Hensikten og bruken av $lookup
Databehandling er avgjørende for å utlede innsikt fra rådata. For eksempel kan en restaurant analysere salgsdata for å identifisere bestselgende varer i helgene, eller for å se hvor mange kopper kaffe som selges til ulike tider på døgnet.
Enkle databasespørringer er ofte utilstrekkelige for slike analyser. MongoDB tilbyr en funksjon som heter aggregeringsrørledning for å håndtere avanserte spørringer.
Aggregeringsrørledningen består av en serie operasjoner, også kalt stadier, som bearbeider data for å produsere et samlet resultat. Stadier som $sort
, $match
, $group
, $merge
, $count
, og $lookup
er eksempler på disse operasjonene. De kan kombineres i ulike rekkefølger for å utføre kompleks databehandling.
$lookup
er et viktig stadium i MongoDBs aggregeringsrørledning, brukt for å utføre en venstre ytre sammenføyning mellom to samlinger. Dette betyr at alle dokumenter fra den venstre samlingen inkluderes i resultatet, sammen med samsvarende dokumenter fra den høyre samlingen. Hvis det ikke finnes en match for dokumenter i venstre samling i den høyre, fylles disse feltene med `null`.
La oss se på to samlinger som illustrerer dette konseptet:
orders_collection: | |||
order_id | customer_id | order_date | total_amount |
1 | 100 | 2022-05-01 | 50.00 |
2 | 101 | 2022-05-02 | 75.00 |
3 | 102 | 2022-05-03 | 100.00 |
customers_collection: | |||
customer_num | customer_name | customer_email | customer_phone |
100 | John | [email protected] | [email protected] |
En venstre ytre sammenføyning av disse to samlingene, basert på customer_id
i orders_collection
og customer_num
i customers_collection
, vil kombinere dokumenter fra begge, med orders_collection
som venstre samling. Resultatet vil inkludere alle ordrer, og kundeinformasjon der det finnes en match.
Resultatet av sammenføyningen:
Det er viktig å merke seg at $lookup
utfører en streng likhetssammenligning. Funksjonen returnerer hele dokumentet som matcher, ikke bare de matchende feltene.
$lookup Syntaks
Syntaksen for $lookup
er som følger:
{ $lookup: { from: <samling for sammenføyning>, localField: <felt fra inndatadokumentene>, foreignField: <felt fra dokumentene i "from" samlingen>, as: <utdata array felt> } }
$lookup
tar fire parametere:
from
: Angir hvilken samling man skal hente dokumenter fra. For eksempel, i vårt tidligere eksempel med ordre- og kundesamlinger, ville vi sattcustomers_collection
her.localField
: Dette er et felt i den primære samlingen som brukes for sammenligning. I eksemplet ovenfor er dettecustomer_id
iorders_collection
.foreignField
: Dette er feltet ifrom
-samlingen som skal sammenlignes med. I vårt eksempel ville det værecustomer_num
icustomers_collection
.as
: Dette er navnet på et nytt felt som vil inneholde en matrise med dokumenter som er resultat av sammenføyningen. Hvis det ikke finnes noen treff vil denne matrisen være tom.
For de to tidligere samlingene kan man utføre en $lookup
operasjon med denne koden, hvor orders_collection
er primærsamlingen:
{ $lookup: { from: "customers_collection", localField: "customer_id", foreignField: "customer_num", as: "customer_info" }
Navnet gitt i `as`-feltet kan være hva som helst, men hvis det samme navnet finnes i det eksisterende dokumentet, vil det feltet overskrives.
Sammenføyning av data fra flere samlinger
MongoDB $lookup
er et viktig stadium i en aggregeringsrørledning. Det er essensielt for komplekse spørringer som krever sammenføyning av data fra ulike samlinger, selv om det ikke er en obligatorisk del av pipelinen.
$lookup
utfører en venstre ytre sammenføyning mellom to samlinger, og resulterer i at et nytt felt opprettes med en matrise av dokumenter fra den andre samlingen. Disse dokumentene velges ut fra om de har match med det angitte feltet. Resultatet er et felt som enten inneholder en matrise med matchende dokumenter, eller en tom matrise hvis det ikke er match.
La oss se på employees
og projects
samlingene:
Vi kan bruke denne koden for å sammenføye de to samlingene:
db.projects.aggregate([ { $lookup: { from: "employees", localField: "employees", foreignField: "_id", as: "assigned_employees" } } ])
Resultatet er en kombinasjon av prosjekter og tilhørende ansatte. Ansatte er representert i en matrise.
Pipeline Stadier som kan brukes sammen med $lookup
Som nevnt kan $lookup
kombineres med andre aggregeringsstadier. For å illustrere dette, bruker vi følgende samlinger:
I MongoDB ser disse ut som følgende:
Noen stadier som kan brukes sammen med $lookup
er:
$match
$match
filtrerer dokumentstrømmen, slik at kun dokumenter som oppfyller en gitt betingelse går videre til neste stadium. Det er best å bruke dette stadiet tidlig i pipelinen for å optimalisere ytelsen.
Ved hjelp av de to tidligere samlingene kan $match
og $lookup
kombineres slik:
db.users.aggregate([ { $match: { country: "USA" } }, { $lookup: { from: "orders", localField: "_id", foreignField: "user_id", as: "orders" } } ])
$match
filtrerer brukere fra USA. Deretter kombineres dette resultatet med $lookup
for å hente bestillingsdetaljer for disse brukerne.
$project
$project
brukes til å omforme dokumenter ved å velge hvilke felt som skal inkluderes, ekskluderes eller legges til. Dette er nyttig for å filtrere bort unødvendige felt, og optimalisere dataoverføringen i pipelinen.
Vi kan kombinere $lookup
og $project
på denne måten:
db.users.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "user_id", as: "orders" } }, { $project: { name: 1, _id: 0, total_spent: { $sum: "$orders.price" } } } ])
Dette kombinerer bruker- og ordresamlinger ved hjelp av $lookup
, og $project
viser kun brukernavn og totalt brukt beløp. Feltet _id
er fjernet.
$unwind
$unwind
dekonstruerer eller oppløser et matrisefelt ved å lage nye dokumenter for hvert element i matrisen. Dette er nyttig hvis man ønsker å utføre aggregeringsoperasjoner på matrisefeltene.
Hvis man ønsker å kjøre aggregering på `hobby` feltet, kan man ikke gjøre det direkte fordi det er en matrise. Men med $unwind
kan dette feltet oppløses før aggregering.
Med bruker- og ordresamlingene kan vi bruke $lookup
og $unwind
sammen slik:
db.users.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "user_id", as: "orders" } }, { $unwind: "$orders" } ])
Her returnerer $lookup
et matrisefelt kalt `orders`, som `unwind` deretter oppløser. Alice dukker opp to ganger, da hun har to bestillinger.
Eksempler på $lookup brukstilfeller
$lookup
er et nyttig verktøy for databehandling, spesielt når man ønsker å kombinere data fra flere samlinger basert på lignende felter. Dette kan enkelt oppnås ved å bruke $lookup
stadiet.
Se på bruker- og ordresamlingene:
De to samlingene kan kombineres ved hjelp av $lookup
, med følgende resultat:
$lookup
er ikke begrenset til å sammenføye to samlinger. Man kan utføre flere $lookup
stadier for å sammenføye data fra mer enn to samlinger. Tenk på følgende tre samlinger:
Med koden nedenfor kan vi sammenføye data fra disse tre samlingene, for å hente alle bestillinger og detaljer om produktene som ble bestilt:
db.orders.aggregate([ { $lookup: { from: "order_items", localField: "_id", foreignField: "order_id", as: "order_items" } }, { $unwind: "$order_items" }, { $lookup: { from: "products", localField: "order_items.product_id", foreignField: "_id", as: "product_details" } }, { $group: { _id: "$_id", customer: { $first: "$customer" }, total: { $sum: "$order_items.price" }, products: { $push: "$product_details" } } } ])
Resultatet av denne operasjonen er vist nedenfor:
Konklusjon
$lookup
er et verdifullt verktøy for databehandling som involverer flere samlinger, og gir muligheten til å trekke konklusjoner basert på data som er lagret i ulike steder. Da databehandling sjeldent bare avhenger av informasjon fra en enkelt samling.
Å kombinere data fra ulike samlinger er et nøkkeltrinn for å trekke meningsfulle konklusjoner. Ved å benytte $lookup
i MongoDBs aggregeringsrørledning, kan man utføre avansert databehandling og få verdifull innsikt fra rådata.
Det anbefales å også utforske andre MongoDB-kommandoer og spørringer for å mestre databehandling i dette miljøet.