Mester MongoDB $lookup: Effektfulle database-sammenføyninger

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 satt customers_collection her.
  • localField: Dette er et felt i den primære samlingen som brukes for sammenligning. I eksemplet ovenfor er dette customer_id i orders_collection.
  • foreignField: Dette er feltet i from-samlingen som skal sammenlignes med. I vårt eksempel ville det være customer_num i customers_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.