Sådan bruger du $lookup i MongoDB

MongoDB er en populær NoSQL-database, der gemmer data i samlinger. MongoDB-samlinger består af et eller flere dokumenter, der indeholder de faktiske data i JSON-format. Dokumenter kan sammenlignes med rækker i traditionelle relationelle SQL-databaser, mens samlinger er analoge med tabeller.

En nøglefunktionalitet i databaser er evnen til at forespørge på de data, der er gemt i databasen. Forespørgsel på data giver mulighed for at hente specifik information, dataanalyse, datarapportering og også dataintegration.

For at kunne forespørge en database effektivt, er det afgørende at kunne kombinere data fra flere tabeller, i tilfælde af SQL-databaser eller flere samlinger i NOSQL-databaser, til et enkelt resultatsæt.

I MongoDB $lookup brugere at kombinere information fra to samlinger, når de forespørger. Den udfører det, der svarer til en venstre ydre joinforbindelse i en SQL-database.

$lookups brug og mål

En vigtig funktion ved databaser er databehandling for at få meningsfuld information ud af rådata.

Hvis du for eksempel driver en restaurantvirksomhed, vil du måske analysere din restaurants data for at finde ud af, hvor meget du tjener hver dag, hvilke fødevarer der er på efterspørgsel i weekenden, eller endda finde ud af, hvor mange kopper kaffe du sælger på hver time på dagen.

Til sådanne behov vil simple databaseforespørgsler ikke være tilstrækkelige. Du skal udføre avancerede forespørgsler på de data, du har gemt. For at imødekomme sådanne behov har MongoDB en funktion kaldet en aggregeringspipeline.

En aggregeringspipeline er et system bestående af komponerbare operationer kaldet stadier, som bruges til at behandle data for at producere et endeligt aggregeret resultat. Eksempler på stadier i aggregeringspipelinen omfatter blandt andet $sort, $match, $group, $merge, $count og $lookup.

Disse trin kan anvendes i enhver rækkefølge i en aggregeringspipeline. På hvert trin i en aggregeringspipeline udføres forskellige operationer på de data, der sendes gennem aggregeringspipelinen.

$lookup er således et trin i MongoDB-aggregationspipelinen. $Lookup bruges til at udføre en venstre ydre joinforbindelse mellem to samlinger i en MongoDB-database. En venstre ydre sammenføjning kombinerer alle dokumenter eller indgange til venstre med matchende dokumenter eller indgange til højre.

Overvej for eksempel de to samlinger nedenfor, som er blevet repræsenteret i tabelformat for lettere forståelse:

ordre_indsamling:

order_idcustomer_idorder_datetotal_amount11002022-05-0150.0021012022-05-0275.0031022022-05-03100.00

kunder_indsamling:

customer_numcustomer_namecustomer_emailcustomer_phone100John [email protected] [email protected]

Hvis vi udfører en venstre ydre sammenføjning på ovenstående samlinger ved hjælp af kunde_id-feltet, som vises i ordresamlingen, hvor ordreindsamlingen er den venstre samling og kundesamlingen er den rigtige samling, vil resultatet indeholde alle dokumenterne i ordresamlingen og dokumenter på kundesamlingen, der har et kundenummer, der matcher et kunde-id for nogen af ​​posterne i ordresamlingen.

  Hyr den bedste produktfotograf til din million-dollar-idé [9 Resources]

Det endelige resultat af den venstre ydre sammenføjning på ordrer og kundesamlinger ser sådan ud, når det er repræsenteret i tabelformat:

Bemærk, at for kunden med kunde_id 101 i ordresamlingen, som ikke havde en tilsvarende værdi for kundenummer i kundesamlingen, er manglende tilsvarende værdier fra kundetabellen blevet udfyldt med null.

$lookup udfører streng lighedssammenligning mellem felter og henter hele dokumentet, der matchede, og ikke kun de felter, der matchede.

$lookup Syntaks

Syntaksen for $lookup er som følger:

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

$lookup har fire parametre:

  • fra – repræsenterer den samling, hvorfra vi ønsker at slå dokumenter op. I vores tidligere eksempel, hvor vi brugte ordre_indsamling og kunder_indsamling, ville vi sætte kunder_indsamling som fra samlingen.
  • localField – dette er et felt i den fungerende eller primære samling, som vi bruger til at sammenligne med felter i vores fra-samling (customers_collection i vores tilfælde). I eksemplet ovenfor ville localField være customer_id, som findes i orders_collection.
  • fremmedField – det er det felt, vi ønsker at sammenligne med i den samling, vi angiver i fra. I vores eksempel ville dette være customer_num fundet i customer_collection, som vi bruger som vores værdi i fra
  • as – dette er et nyt feltnavn, som vi angiver til at repræsentere det felt, der vises i vores dokument, som indeholder dokumenter, der stammer fra match mellem localField og fremmedfelt. Alle disse kampe er sat i et array i dette felt. Hvis der ikke er nogen match, vil dette felt indeholde en tom matrix.

Fra vores to tidligere samlinger ville vi bruge følgende kode til at udføre en $opslagsoperation på de to samlinger med orders_collection som vores arbejds- eller primære samling.

{
    $lookup: {
      from: "customers_collection",
      localField: "customer_id",
      foreignField: "customer_num",
      as: "customer_info"
 }

Bemærk, at as-feltet kan være en hvilken som helst strengværdi. Men hvis du giver det et navn, der allerede findes i arbejdsdokumentet, vil det felt blive overskrevet.

Sammenføjning af data fra flere samlinger

MongoDB $lookup er en nyttig fase i en aggregeringspipeline i MongoDB. Selvom det ikke er et krav, at en aggregeringspipeline i MongoDB skal have et $opslagsstadium, er stadiet afgørende, når der udføres komplekse forespørgsler, der kræver sammenføjning af data på tværs af flere samlinger.

$lookup-stadiet udfører en venstre ydre joinforbindelse på to samlinger, hvilket resulterer i, at et nyt felt oprettes, eller at et eksisterende felts værdier overskrives med et array, der indeholder dokumenter fra en anden samling.

Disse dokumenter vælges ud fra, om de har værdier, der matcher værdierne i det felt, de sammenlignes med. Slutresultatet er et felt, der indeholder en række dokumenter i tilfælde, der blev fundet match, eller en tom matrix, hvis der ikke blev fundet nogen match.

  Bedste 10 Microsoft Teams-funktioner

Overvej medarbejderens og projektsamlingerne vist nedenfor.

Vi kan bruge følgende kode til at deltage i de to samlinger:

db.projects.aggregate([
   {
      $lookup: {
         from: "employees",
         localField: "employees",
         foreignField: "_id",
         as: "assigned_employees"
      }
   }
])

Resultatet af denne operation er en kombination af de to samlinger. Resultatet er projekterne og alle de medarbejdere, der er tilknyttet hvert projekt. Medarbejderne er repræsenteret i et array.

Pipeline Stages, der kan bruges sammen med $lookup

Som nævnt før er $lookup et trin i en MongoDB aggregeringspipeline, og det kan bruges sammen med andre aggregeringspipelinetrin. For at vise, hvordan disse stadier kan bruges sammen med $lookup, vil vi bruge følgende to samlinger til illustrationsformål.

I MongoDB er de gemt i JSON-format. Sådan ser ovenstående samlinger ud i MongoDB.

Nogle eksempler på aggregeringspipelinestadier, der kan bruges sammen med $lookup, inkluderer:

$match

$match er et aggregeringspipelinetrin, der bruges til at filtrere dokumentstrømmen for kun at tillade de dokumenter, der opfylder den givne betingelse, at fortsætte til næste trin i aggregeringspipelinen. Dette trin bruges bedst tidligt i pipelinen til at fjerne dokumenter, der ikke er nødvendige, og dermed optimere aggregeringspipelinen.

Ved at bruge de to tidligere samlinger kan du kombinere $match og $lookup sådan:

db.users.aggregate([
   {
      $match: {
         country: "USA"
      }
   },
   {
      $lookup: {
         from: "orders",
         localField: "_id",
         foreignField: "user_id",
         as: "orders"
      }
   }
])

$match bruges til at filtrere efter brugere fra USA. Resultatet fra $match kombineres derefter med $lookup for at få ordredetaljerne for brugere fra USA. Resultatet af ovenstående operation er vist nedenfor:

$projekt

$project er et trin, der bruges til at omforme dokumenter ved at specificere, hvilke felter der skal inkluderes, ekskluderes eller tilføjes til dokumenter. For eksempel, hvis du behandler dokumenter med ti felter hver, men kun fire felter i dokumenterne indeholder data, som du har brug for til din databehandling, kan du bruge $project til at filtrere de felter, du ikke har brug for.

Dette giver dig mulighed for at undgå at sende unødvendige data til næste fase af din aggregeringspipeline.

Vi kan kombinere $lookup og $project således:

db.users.aggregate([
   {
      $lookup: {
         from: "orders",
         localField: "_id",
         foreignField: "user_id",
         as: "orders"
      }
   },
   {
      $project: {
         name: 1,
         _id: 0,
         total_spent: { $sum: "$orders.price" }
      }
   }
])

Ovenstående kombinerer bruger- og ordresamlingerne ved hjælp af $lookup, derefter bruges $project til kun at vise navnet på hver bruger og det beløb, hver bruger har brugt. $project bruges også til at fjerne _id-feltet fra resultaterne. Resultatet af ovenstående operation er vist nedenfor:

$slappe af

$unwind er et aggregeringstrin, der bruges til at dekonstruere eller afvikle et arrayfelt, der skaber nye dokumenter for hvert element i arrayet. Dette er nyttigt, hvis du ønsker at køre en vis aggregering på array-feltværdierne.

  8 bedste Batman-videospil at eje

For eksempel, i eksemplet nedenfor, hvis du ønsker at køre aggregering på hobbyområdet, kan du ikke gøre det, fordi det er et array. Du kan dog bruge unwind det ved at bruge $unwind og derefter udføre sammenlægninger på de resulterende dokumenter.

Ved at bruge bruger- og ordresamlingerne kan vi bruge $lookup og $unwind sammen sådan:

db.users.aggregate([
   {
      $lookup: {
         from: "orders",
         localField: "_id",
         foreignField: "user_id",
         as: "orders"
      }
   },
   {
      $unwind: "$orders"
   }
])

I koden ovenfor returnerer $lookup et matrixfelt kaldet ordrer. $unwind bruges derefter til at afvikle arrayfeltet. Resultatet af denne operation er vist nedenfor: Bemærk, at Alice dukker op to gange, fordi hun havde to ordrer.

Eksempler på $lookup Use Cases

Når du udfører databehandling, er $lookup et nyttigt værktøj. For eksempel kan du have to samlinger, som du vil tilslutte dig baseret på felter på samlingerne, som har lignende data. Et simpelt $opslagstrin kan bruges til at gøre dette og tilføje et nyt felt i de primære samlinger, som indeholder dokumenter hentet fra en anden samling.

Tager hensyn til brugere og ordresamlinger vist nedenfor:

De to samlinger kan kombineres ved hjælp af $lookup for at give resultatet vist nedenfor:

$lookup kan også bruges til at udføre mere komplekse joinforbindelser. $lookup er ikke kun begrænset til at udføre joining på to samlinger. Du kan implementere flere $lookup-stadier for at udføre joinforbindelser på mere end to samlinger. Overvej de tre samlinger vist nedenfor:

Vi kan bruge koden nedenfor til at udføre en mere kompleks sammenføjning på tværs af de tre samlinger for at få alle de ordrer, der blev foretaget, og også detaljer om de produkter, der blev bestilt.

Koden nedenfor giver os mulighed for at gøre netop det:

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 af ovenstående operation er vist nedenfor:

Konklusion

Når du udfører databehandling, der involverer flere samlinger, kan $lookup være nyttig, da det giver dig mulighed for at samle data og drage konklusioner baseret på data gemt i flere samlinger. Databehandling er sjældent afhængig af kun én samling.

For at drage meningsfulde konklusioner ud fra data er det et vigtigt skridt at samle data på tværs af flere samlinger. Overvej derfor at bruge $lookup-stadiet i din MongoDB-aggregationspipeline for at give dig mulighed for at behandle dine data bedre og få meningsfuld indsigt fra rådata, der er lagret på tværs af samlinger.

Du kan også udforske nogle MongoDB-kommandoer og -forespørgsler.