07_SimpleMongoQuery
PDF-Dokumente
| Dateiname | Aktion |
|---|---|
| PDFFolie_SimpleMongoQuery.pdf | Öffnen |
| PDFUebung_SimpleMongoQuery.pdf | Öffnen |
Videos
| Dateiname | Aktion |
|---|---|
| VIDEOVideo_Pizza_D | Abspielen |
| VIDEOVideo_SimpleMongoQuery_D | Abspielen |
Lernmaterialien
Simple query
SELECT * FROM table
Die SQL-Abfrage
SELECT * FROM customer;entspricht in MongoDB einfach:
db.customer.find({})Falls du die Daten schön formatiert sehen willst:
db.customer.find({}).pretty()Warum:
SELECT * bedeutet „alle Spalten“, und find({})
bedeutet „alle Dokumente der Collection“.
Die hochgeladene Datei zeigt, dass customer als
Dokument-Collection mit verschachtelten Feldern wie adress
und order aufgebaut ist.
Zum Vergleich:
SQL:
SELECT * FROM customer;MongoDB:
db.customer.find({})
Falls du möchtest, kann ich dir auch gleich weitere SQL-Abfragen wie
WHERE, JOIN, GROUP BY oder
ORDER BY für diese MongoDB-Datenstruktur
umschreiben.
SELECT Attribute FROM table
Wenn du in SQL nur bestimmte Attribute auswählst, zum Beispiel:
SELECT first_name, last_name, eMail FROM customer;dann ist das in MongoDB:
db.customer.find(
{},
{ first_name: 1, last_name: 1, eMail: 1 }
)Mit schöner Ausgabe:
db.customer.find(
{},
{ first_name: 1, last_name: 1, eMail: 1 }
).pretty()Wichtig:
1bedeutet: Feld anzeigen_idwird in MongoDB standardmäßig mit ausgegeben
Wenn du _id nicht sehen willst:
db.customer.find(
{},
{ _id: 0, first_name: 1, last_name: 1, eMail: 1 }
)Beispiel passend zu deiner Datenstruktur mit verschachtelten
Attributen wie adress.city_name:
db.customer.find(
{},
{ _id: 0, first_name: 1, "adress.city_name": 1 }
)Also allgemein:
SELECT attribut1, attribut2 FROM customer;wird zu
db.customer.find(
{},
{ attribut1: 1, attribut2: 1 }
)Ein Beispiel mit deinem product-Dokument wäre etwa
product_type und prduct_name auswählen.
Wenn du willst, schreibe ich dir jetzt als Nächstes
SELECT ... WHERE ... in MongoDB um.
unwind
Gerne.
$unwind wird in MongoDB verwendet, um ein Array
aufzulösen.
Das bedeutet: Aus einem Dokument mit einer Liste werden
mehrere Dokumente, jeweils eins pro
Array-Element.
In deiner customer-Struktur ist order ein
Array, und innerhalb jeder Bestellung ist product nochmal
ein Array.
Ohne $unwind
Ein Kunde sieht vereinfacht so aus:
{
first_name: "Anna",
last_name: "Schmidt",
order: [
{ order_date: "2025-01-05T18:30:00Z", ... },
{ order_date: "2025-01-22T18:30:00Z", ... },
{ order_date: "2025-02-08T18:30:00Z", ... }
]
}Hier hat ein Dokument mehrere Bestellungen.
Mit $unwind: "$order"
Dann wird aus einem Kundendokument mit 3 Bestellungen 3 Dokumente:
db.customer.aggregate([
{ $unwind: "$order" }
])Ergebnis vereinfacht:
{ first_name: "Anna", last_name: "Schmidt", order: { order_date: "2025-01-05T18:30:00Z", ... } }
{ first_name: "Anna", last_name: "Schmidt", order: { order_date: "2025-01-22T18:30:00Z", ... } }
{ first_name: "Anna", last_name: "Schmidt", order: { order_date: "2025-02-08T18:30:00Z", ... } }Also:
vorher: 1 Kunde mit Liste von Bestellungen
nachher: 1 Zeile pro Bestellung
Warum braucht man das?
Weil MongoDB bei vielen Operationen mit einzelnen Elementen arbeiten muss, nicht mit einer ganzen Liste.
Zum Beispiel wenn du:
auf jede Bestellung einzeln zugreifen willst
nach Bestellungen filtern willst
mit Feldern in jeder Bestellung weiterarbeiten willst
später einen Join auf Produkte machen willst
Zweites $unwind in deiner Struktur
In jeder Bestellung gibt es zusätzlich das Array
order.product.
Beispiel:
{
order_date: "2025-01-05T18:30:00Z",
product: [
{ product_id: "000...005", product_name: "Margherita Pizza" },
{ product_id: "000...007", product_name: "Garlic Bread" },
{ product_id: "000...009", product_name: "Cola 0.5L" }
]
}Wenn du auch dieses Array auflösen willst:
db.customer.aggregate([
{ $unwind: "$order" },
{ $unwind: "$order.product" }
])Dann erhältst du:
1 Dokument pro Kunde
pro Bestellung
pro Produkt
Also z. B. für Anna mehrere Zeilen, jeweils eine pro bestelltem Produkt.
Anschaulich
$unwind ist ähnlich wie:
eine Liste „aufklappen“
jede Listenzeile einzeln machen
aus 1:n wieder einzelne Datensätze erzeugen
Warum vor dem INNER JOIN?
Beim Join wollten wir order.product.product_id mit
product._id verbinden.
Das Problem:
order ist ein Array und order.product auch ein
Array.
Darum muss man erst mit $unwind auf ein konkretes
Produkt pro Dokument kommen.
Erst danach ist ein Join mit $lookup sauber möglich.
SELECT * FROM table1 inner join table2
Ein INNER JOIN wird in MongoDB normalerweise mit
$lookup umgesetzt.
Wichtig: MongoDB kennt nicht direkt den SQL-Befehl
INNER JOIN wie relationale Datenbanken. Das Gegenstück ist
meist eine Aggregation mit $lookup.
SQL-Beispiel:
SELECT *
FROM customer c
INNER JOIN product p
ON c.product_id = p._id;In deiner Datenstruktur ist der Join etwas spezieller, weil:
customereine verschachtelte Listeorderdarin wieder eine Liste
productund dort das Feld
product_id
enthält.
Die Produktdaten liegen separat in product mit
_id.
Dafür brauchst du in MongoDB:
db.customer.aggregate([
{ $unwind: "$order" },
{ $unwind: "$order.product" },
{
$lookup: {
from: "product",
localField: "order.product.product_id",
foreignField: "_id",
as: "product_details"
}
},
{ $unwind: "$product_details" }
])Warum das ein INNER JOIN ist:
$lookupverbindetcustomermitproductdas letzte
$unwind: "$product_details"sorgt dafür, dass nur Treffer bleibendamit verhält es sich wie ein INNER JOIN
Ein sinnvolleres Ergebnis, also nur ausgewählte Felder:
db.customer.aggregate([
{ $unwind: "$order" },
{ $unwind: "$order.product" },
{
$lookup: {
from: "product",
localField: "order.product.product_id",
foreignField: "_id",
as: "product_details"
}
},
{ $unwind: "$product_details" },
{
$project: {
_id: 0,
first_name: 1,
last_name: 1,
"order.order_date": 1,
"order.product.product_id": 1,
"order.product.product_name": 1,
"product_details.product_type": 1,
"product_details.product_decription": 1
}
}
])SQL-Logik dazu wäre ungefähr:
SELECT c.first_name, c.last_name, op.product_id, p.product_type, p.product_decription
FROM customer c
INNER JOIN order_product op ON ...
INNER JOIN product p ON op.product_id = p._id;Merksatz:
SQL
INNER JOINin MongoDB meist
$lookup+$unwind
SELECT GROUP BY
Gerne.
Ein SELECT ... GROUP BY wird in MongoDB mit
aggregate() und
$group umgesetzt.
SQL-Beispiel
SELECT city_name, COUNT(*)
FROM customer
GROUP BY city_name;MongoDB
Da city_name bei dir in adress.city_name
steckt, ist die passende MongoDB-Abfrage:
db.customer.aggregate([
{
$group: {
_id: "$adress.city_name",
anzahl_kunden: { $sum: 1 }
}
}
])Die Kundendaten enthalten das verschachtelte Feld
adress.city_name, daher wird genau dieses Feld im
$group verwendet.
Erklärung
aggregate([...])startet die Aggregation$groupentspricht dem SQL-GROUP BY_idist das Gruppierungsfeld{ $sum: 1 }zählt die Dokumente pro Gruppe
Mit schönerer Ausgabe
Wenn du statt _id lieber einen sprechenden Feldnamen
möchtest:
db.customer.aggregate([
{
$group: {
_id: "$adress.city_name",
anzahl_kunden: { $sum: 1 }
}
},
{
$project: {
_id: 0,
city_name: "$_id",
anzahl_kunden: 1
}
}
])Weiteres Beispiel: Produkte nach Typ gruppieren
Aus deiner product-Collection kann man auch nach
product_type gruppieren.
SQL
SELECT product_type, COUNT(*)
FROM product
GROUP BY product_type;MongoDB
db.product.aggregate([
{
$group: {
_id: "$product_type",
anzahl: { $sum: 1 }
}
}
])Mit SUM statt COUNT
SQL
SELECT restaurant_name, SUM(number_of_pieces)
FROM customer
GROUP BY restaurant_name;Da restaurant_name und number_of_pieces in
deinem Array order.product liegen, muss man vorher
unwind verwenden.
MongoDB
db.customer.aggregate([
{ $unwind: "$order" },
{ $unwind: "$order.product" },
{
$group: {
_id: "$order.product.restaurant_name",
gesamt_menge: { $sum: "$order.product.number_of_pieces" }
}
}
])Merksatz
SQL
GROUP BY→ MongoDB$groupSQL
COUNT(*)→ MongoDB{ $sum: 1 }SQL
SUM(feld)→ MongoDB{ $sum: "$feld" }
Allgemeines Muster
SELECT feld, COUNT(*)
FROM tabelle
GROUP BY feld;wird zu
db.tabelle.aggregate([
{
$group: {
_id: "$feld",
anzahl: { $sum: 1 }
}
}
])