Hoe $ lookup te gebruiken in MongoDB

MongoDB is een populaire NoSQL-database die gegevens opslaat in collecties. MongoDB-collecties bestaan ​​uit een of meer documenten die de daadwerkelijke gegevens in JSON-indeling bevatten. Documenten zijn vergelijkbaar met rijen in traditionele relationele SQL-databases, terwijl verzamelingen analoog zijn aan tabellen.

Een belangrijke functionaliteit in databases is de mogelijkheid om de gegevens die in de database zijn opgeslagen op te vragen. Het opvragen van gegevens maakt het ophalen van specifieke informatie, gegevensanalyse, gegevensrapportage en ook gegevensintegratie mogelijk.

Om een ​​database effectief te kunnen bevragen, is het cruciaal om gegevens uit meerdere tabellen, in het geval van SQL-databases of meerdere collecties in NOSQL-databases, te kunnen combineren tot één resultatenset.

In MongoDB $lookup-gebruikers om informatie uit twee verzamelingen te combineren bij het opvragen. Het voert het equivalent uit van een left outer join in een SQL-database.

Gebruik en doel van $lookup

Een belangrijke functie van databases is gegevensverwerking om zinvolle informatie uit ruwe gegevens te halen.

Als u bijvoorbeeld een restaurantbedrijf runt, wilt u misschien de gegevens van uw restaurant analyseren om erachter te komen hoeveel u elke dag maakt, welke voedingsmiddelen in het weekend in trek zijn, of zelfs om erachter te komen hoeveel kopjes koffie u verkoopt bij elk uur van de dag.

Voor dergelijke behoeften zijn eenvoudige databasequery’s niet voldoende. U moet geavanceerde query’s uitvoeren op de gegevens die u hebt opgeslagen. Om aan dergelijke behoeften te voldoen, heeft MongoDB een functie die een aggregatiepijplijn wordt genoemd.

Een aggregatiepijplijn is een systeem dat bestaat uit samenstelbare bewerkingen, stadia genaamd, die worden gebruikt om gegevens te verwerken om een ​​uiteindelijk geaggregeerd resultaat te produceren. Voorbeelden van fasen in de aggregatiepijplijn zijn onder andere $sort, $match, $group, $merge, $count en $lookup.

Deze stadia kunnen in elke volgorde worden toegepast in een aggregatiepijplijn. In elke fase van een aggregatiepijplijn worden verschillende bewerkingen uitgevoerd op de gegevens die door de aggregatiepijplijn worden geleid.

$lookup is dus een fase in de MongoDB-aggregatiepijplijn. $Lookup wordt gebruikt om een ​​left outer join uit te voeren tussen twee collecties in een MongoDB-database. Een left outer join combineert alle documenten of ingangen aan de linkerkant met overeenkomende documenten of ingangen aan de rechterkant.

Kijk bijvoorbeeld eens naar de twee onderstaande verzamelingen, die voor een beter begrip in tabelvorm zijn weergegeven:

bestellingen_collectie:

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

klanten_collectie:

customer_numcustomer_namecustomer_emailcustomer_phone100John [email protected] [email protected]

Als we een left outer join uitvoeren op de bovenstaande collecties met behulp van het veld customer_id, dat verschijnt in de order_collection, waarbij de order_collection de linker collectie is en de customers_collection de juiste collectie, zal het resultaat alle documenten in de Orders Collection en documenten bevatten op de Customers Collection die een customer_num hebben dat overeenkomt met een customer_id van een van de records in de Orders Collection.

  Hoe contacten, oproeplog en berichten van de ene telefoon naar de andere over te zetten met MobileTrans

Het uiteindelijke resultaat van de left outer join-bewerking op de bestellingen en klantenverzamelingen ziet er als volgt uit wanneer weergegeven in tabelvorm:

Merk op dat voor de klant met customer_id 101 in de Orders Collection, die geen overeenkomende customer_num-waarde had in de Customers Collection, ontbrekende corresponderende waarden uit de klantentabel zijn gevuld met null.

$lookup voert een strikte gelijkheidsvergelijking uit tussen velden en haalt het volledige document op dat overeenkwam, en niet alleen de velden die overeenkwamen.

$lookup-syntaxis

De syntax voor $lookup is als volgt:

{
   $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 heeft vier parameters:

  • van – vertegenwoordigt de verzameling waaruit we documenten willen opzoeken. In ons eerdere voorbeeld met orders_collection en customers_collection, zouden we customers_collection als de from the collection plaatsen.
  • localField – dit is een veld in de werkende of primaire collectie die we gebruiken om te vergelijken met velden in onze from-collectie (customers_collection in ons geval). In het bovenstaande voorbeeld zou het localField customer_id zijn, wat te vinden is in de orders_collection.
  • ForeignField – dit is het veld waarmee we willen vergelijken in de verzameling waaruit we specificeren. In ons voorbeeld is dit customer_num gevonden in de customer_collection die we gebruiken als onze waarde in from
  • as – dit is een nieuwe veldnaam die we specificeren om het veld weer te geven dat zal verschijnen in ons document, dat documenten bevat die het resultaat zijn van overeenkomsten tussen het localField en het foreignField. Al deze overeenkomsten worden in dit veld in een array geplaatst. Als er geen overeenkomsten zijn, bevat dit veld een lege matrix.

Van onze twee eerdere collecties zouden we de volgende code gebruiken om een ​​$lookup-bewerking uit te voeren op de twee collecties met de orders_collection als onze werk- of primaire collectie.

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

Merk op dat het as-veld elke tekenreekswaarde kan zijn. Als u het echter een naam geeft die al bestaat in het werkdocument, wordt dat veld overschreven.

Gegevens uit meerdere verzamelingen samenvoegen

MongoDB $lookup is een nuttige fase in een aggregatiepijplijn in MongoDB. Hoewel het geen vereiste is dat een aggregatiepijplijn in MongoDB een $lookup-fase moet hebben, is de fase cruciaal bij het uitvoeren van complexe query’s waarbij gegevens uit meerdere verzamelingen moeten worden samengevoegd.

De fase $lookup voert een left outer join uit op twee verzamelingen, wat ertoe leidt dat een nieuw veld wordt gemaakt of dat de waarden van een bestaand veld worden overschreven door een array met documenten uit een andere verzameling.

Deze documenten worden geselecteerd op basis van of ze waarden hebben die overeenkomen met de waarden van het veld waarmee ze worden vergeleken. Het eindresultaat is een veld dat een reeks documenten bevat voor het geval er overeenkomsten zijn gevonden of een lege reeks voor het geval er geen overeenkomsten zijn gevonden.

  10 beste projectieschermen om sport- en filmavonden te organiseren

Overweeg de hieronder getoonde werknemers- en projectcollecties.

We kunnen de volgende code gebruiken om de twee verzamelingen samen te voegen:

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

Het resultaat van deze operatie is een combinatie van de twee collecties. Het resultaat zijn de projecten en alle medewerkers die aan elk project zijn toegewezen. De medewerkers zijn vertegenwoordigd in een array.

Pijplijnstadia die samen met $lookup kunnen worden gebruikt

Zoals eerder vermeld, is $lookup een fase in een MongoDB-aggregatiepijplijn en kan deze samen met andere aggregatiepijplijnstadia worden gebruikt. Om te laten zien hoe deze fasen samen met $lookup kunnen worden gebruikt, gebruiken we de volgende twee verzamelingen ter illustratie.

In MongoDB worden ze opgeslagen in JSON-indeling. Zo zien de bovenstaande collecties eruit in MongoDB.

Enkele voorbeelden van aggregatiepijplijnfasen die samen met $lookup kunnen worden gebruikt, zijn:

$overeenkomst

$match is een aggregatiepijplijnstadium dat wordt gebruikt om de documentstroom te filteren, zodat alleen die documenten die aan de gegeven voorwaarde voldoen, doorgaan naar het volgende stadium in de aggregatiepijplijn. Deze fase kan het beste vroeg in de pijplijn worden gebruikt om documenten te verwijderen die niet nodig zijn en zo de aggregatiepijplijn te optimaliseren.

Met behulp van de twee eerdere verzamelingen kunt u $match en $lookup als volgt combineren:

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

$match wordt gebruikt om te filteren op gebruikers uit de VS. Het resultaat van $match wordt vervolgens gecombineerd met $lookup om de bestelgegevens van gebruikers uit de VS te krijgen. Het resultaat van de bovenstaande bewerking wordt hieronder weergegeven:

$project

$project is een fase die wordt gebruikt om documenten een nieuwe vorm te geven door te specificeren welke velden moeten worden opgenomen, uitgesloten of toegevoegd aan documenten. Als u bijvoorbeeld documenten verwerkt met elk tien velden, maar slechts vier velden in de documenten gegevens bevatten die u nodig heeft voor uw gegevensverwerking, kunt u $project gebruiken om de velden die u niet nodig heeft te filteren.

Hierdoor kunt u voorkomen dat onnodige gegevens naar de volgende fase van uw aggregatiepijplijn worden gestuurd.

We kunnen $lookup en $project als volgt combineren:

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

Het bovenstaande combineert de gebruikers en bestelt verzamelingen met behulp van $lookup, waarna $project wordt gebruikt om alleen de naam van elke gebruiker en het door elke gebruiker uitgegeven bedrag weer te geven. $project wordt ook gebruikt om het veld _id uit de resultaten te verwijderen. Het resultaat van bovenstaande bewerking is hieronder weergegeven:

  Waarom werkt mijn Paramount Plus niet op mijn tv?

$ontspan

$unwind is een aggregatiefase die wordt gebruikt om een ​​arrayveld te deconstrueren of af te wikkelen, waarbij nieuwe documenten worden gemaakt voor elk element in de array. Dit is handig als u aggregatie wilt uitvoeren op de matrixveldwaarden.

Als u bijvoorbeeld in het onderstaande voorbeeld aggregatie wilt uitvoeren op het veld hobby’s, kunt u dit niet doen omdat het een array is. U kunt het echter afwikkelen met $unwind en vervolgens aggregaties uitvoeren op de resulterende documenten.

Met behulp van de verzamelingen gebruikers en bestellingen kunnen we $lookup en $unwind als volgt samen gebruiken:

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

In de bovenstaande code retourneert $lookup een arrayveld met de naam orders. $unwind wordt dan gebruikt om het arrayveld af te wikkelen. Het resultaat van deze bewerking wordt hieronder weergegeven: Merk op dat Alice twee keer verschijnt omdat ze twee bestellingen had.

Voorbeelden van $lookup Use Cases

Bij het uitvoeren van gegevensverwerking is $lookup een handig hulpmiddel. U kunt bijvoorbeeld twee collecties hebben die u wilt samenvoegen op basis van velden in de collecties die vergelijkbare gegevens hebben. Een eenvoudige $lookup-fase kan worden gebruikt om dit te doen en een nieuw veld toe te voegen aan de primaire verzamelingen, die documenten bevatten die uit een andere verzameling zijn verkregen.

Houdt rekening met de hieronder getoonde gebruikers- en orderverzamelingen:

De twee verzamelingen kunnen worden gecombineerd met behulp van $lookup om het onderstaande resultaat te geven:

$lookup kan ook worden gebruikt om complexere joins uit te voeren. $lookup is niet alleen beperkt tot het samenvoegen van twee collecties. U kunt meerdere $lookup-fasen implementeren om joins uit te voeren op meer dan twee collecties. Overweeg de drie onderstaande collecties:

We kunnen de onderstaande code gebruiken om een ​​complexere samenvoeging uit te voeren tussen de drie collecties om alle bestellingen te krijgen die zijn gemaakt en ook details van de producten die zijn besteld.

Met de onderstaande code kunnen we precies dat doen:

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" }
      }
   }
])

Het resultaat van de bovenstaande bewerking wordt hieronder weergegeven:

Conclusie

Bij het uitvoeren van gegevensverwerking waarbij meerdere verzamelingen betrokken zijn, kan $lookup nuttig zijn, omdat u hiermee gegevens kunt samenvoegen en conclusies kunt trekken op basis van gegevens die in meerdere verzamelingen zijn opgeslagen. Gegevensverwerking is zelden afhankelijk van slechts één verzameling.

Om zinvolle conclusies te trekken uit gegevens, is het samenvoegen van gegevens uit meerdere verzamelingen een belangrijke stap. Overweeg daarom om de $lookup-fase in uw MongoDB-aggregatiepijplijn te gebruiken, zodat u uw gegevens beter kunt verwerken en zinvolle inzichten kunt halen uit onbewerkte gegevens die in verschillende collecties zijn opgeslagen.

U kunt ook enkele MongoDB-opdrachten en -query’s verkennen.