Commit 0b95270a authored by Marcel Huber's avatar Marcel Huber
Browse files

Merge branch 'feature_48-Rework-manual-join-section-of-MongoDBIntro' into develop

parents 6ed4ce4b 9828621e
Pipeline #40371 passed with stages
in 3 minutes and 27 seconds
......@@ -297,7 +297,7 @@ Weiterführende Informationen zu diesen Aufgaben finden Sie in https://github.co
Verwenden Sie für diese Übung eine neue Datenbank `uebung2`.
.Basisdaten
.Basisdaten der Collection `unicorns`
[source,javascript]
----
{_id: ObjectId("5cc6e5d94249f49a59ac4000"), name: "Horny", dob: new Date(1992,2,13,7,47), loves: ["carrot","papaya"], weight: 600, gender: "m", vampires: 63},
......@@ -735,15 +735,14 @@ In dieser Aufgabe sollen Sie die verschiedenen Varianten kennenlernen.
Weiterführende Informationen zu dieser Aufgabe finden Sie auch in https://github.com/karlseguin/the-little-mongodb-book/blob/master/en/mongodb.markdown#chapter-4---data-modeling[Data Modeling] von The Little MongoDB Book.
.Daten
.Daten der Collection `employees`
[source,javascript]
----
db.employees.insertMany([
{_id: ObjectId("4d85c7039ab0fd70a117d730"), name: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d731"), name: "Duncan", manager: ObjectId("4d85c7039ab0fd70a117d730")},
{_id: ObjectId("4d85c7039ab0fd70a117d732"), name: "Moneo", manager: ObjectId("4d85c7039ab0fd70a117d730")},
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")]},
{_id: ObjectId("4d85c7039ab0fd70a117d734"), name: "Ghanima", family: {mother: "Chani", father: "Paul", brother: ObjectId("4d85c7039ab0fd70a117d730")}}
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")]}
])
----
......@@ -771,27 +770,13 @@ db.employees.findOne({_id: db.employees.find({name:"Moneo"})[0].manager})
----
=====
endif::exercise_solution[]
ifdef::blubby[]
. Finden Sie die Kinder von *Chani*.
// aus einer früheren Aufgabe?!
ifdef::exercise_solution[]
+
[example,title=""]
=====
.Kinder von *Chani*
[source, javascript]
----
db.employees.find({'family.mother': "Chani"})
=====
endif::exercise_solution[]
endif::blubby[]
[id='mongodb-joins-graphlookup']
==== Aufgabe {ex_number}{counter:subtopic}: Joins mit `$graphLookup` Operator
In dieser Aufgabe verwenden wir die https://docs.mongodb.com/manual/aggregation/[Aggregation Pipeline] und den https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/[`$graphLookup`] Operator.
.Daten
.Daten der Collection `employees`
[source,javascript]
----
{_id: ObjectId("4d85c7039ab0fd70a117d730"), name: "Leto"},
......@@ -830,7 +815,10 @@ db.employees.aggregate([
{ $match: { "name":"Moneo"} },
{ $project: { _id:0, name:1, manager:1, managerDocs:1 } }
])
----
.Resultat der Abfrage
[source, javascript]
----
{ "name" : "Moneo", "manager" : "Leto", "managerDocs" : [ { "_id" : ObjectId("4d85c7039ab0fd70a117d730"), "name" : "Leto" } ] }
----
=====
......@@ -841,30 +829,160 @@ endif::exercise_solution[]
Finden Sie eine Möglichkeit einen Join mittels https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/[`$lookup`] Operator durchzuführen?
Welche Daten passen dazu besser, die von <<mongodb-joins-manual>> oder von <<mongodb-joins-graphlookup>>
.[#lookup-manager-moneo]#Q{counter:query_number} Manager von *Moneo*#
Erstellen Sie eine Abfrage um den Manager von *Moneo* anzuzeigen.
.[#lookup-manager-moneo-which-data]#Q{counter:query_number} Passendes DataSet#
Welche Daten passen besser zu einer einfachen `$lookup` Abfrage, die von <<mongodb-joins-manual>> oder von <<mongodb-joins-graphlookup>>?
ifndef::exercise_solution[]
[example,title=""]
=====
{nbsp}
{nbsp}
=====
endif::exercise_solution[]
ifdef::exercise_solution[]
[example,title=""]
=====
Die Daten der Aufgabe <<mongodb-joins-graphlookup>> passen gut für diese einfache Join Abfrage über verschiedene Collections.
=====
endif::exercise_solution[]
{nbsp}
.[#lookup-manager-moneo]#Q{counter:query_number} Manager von *Moneo* ermitteln#
Erstellen Sie eine Abfrage um den Manager von *Moneo* anzuzeigen unter Verwendung von `localField` und `foreignField`.
.Daten der Collection `employees`
[source,javascript]
----
{_id: ObjectId("4d85c7039ab0fd70a117d730"), name: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d731"), name: "Duncan", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d732"), name: "Moneo", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: ["Leto", "Moneo"] }
----
[example,title=""]
=====
.Manager von *Moneo* mit einfachem `$lookup` Aggregat
ifdef::exercise_solution[]
[source,javascript]
----
db.employees.aggregate({
$lookup: {
from: "employees",
localField: "manager",
foreignField: "name",
as: "managers"
}
}, {
$match: {
"name": "Moneo"
}
}, {
$project: {
_id: 0,
manager: 0,
managers: {
_id: 0,
manager: 0
}
}
})
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Abfrage
ifdef::exercise_solution[]
[source, javascript]
----
{ "name" : "Moneo", "managers" : [ { "name" : "Leto" } ] }
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
.[#lookup-manager-moneo]#Q{counter:query_number} Manager von *Moneo* über verschiedene Collections ermitteln#
Erstellen Sie eine Abfrage um den Manager von *Moneo* anzuzeigen wenn die Daten in zwei unterschiedlichen Collections abgelegt sind.
.Daten der beiden Collections
[source,javascript]
----
db.employees.insertMany([
{_id: ObjectId("4d85c7039ab0fd70a117d731"), name: "Duncan", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d732"), name: "Moneo", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: ["Leto", "Moneo"]}
])
db.managers.insertMany([
{_id: ObjectId("4d85c7039ab0fd70a117d740"), name: "Leto", department: "Sales"},
{_id: ObjectId("4d85c7039ab0fd70a117d741"), name: "Moneo", department: "Research"}
])
----
[example,title=""]
=====
.Manager von *Moneo* mit `$lookup`
[source, subs="attributes", javascript]
ifdef::exercise_solution[]
[source, javascript]
----
tbd.
db.employees.aggregate({
$lookup: {
from: "managers",
localField: "manager",
foreignField: "name",
as: "managers"
}
}, {
$match: {
"name": "Moneo"
}
}, {
$project: {
_id: 0,
manager: 0,
managers: {
_id: 0
}
}
})
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Abfrage
ifdef::exercise_solution[]
[source, javascript]
----
{ "name" : "Duncan", "managers" : [ { "name" : "Leto", "department" : "Sales" } ] }
{ "name" : "Moneo", "managers" : [ { "name" : "Leto", "department" : "Sales" } ] }
{ "name" : "Siona", "managers" : [ { "name" : "Leto", "department" : "Sales" }, { "name" : "Moneo", "department" : "Research" } ] }
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
include::{exercises_dir}MongodbShardingScalingOut.asc[]
......
......@@ -297,7 +297,7 @@ Weiterführende Informationen zu diesen Aufgaben finden Sie in https://github.co
Verwenden Sie für diese Übung eine neue Datenbank `uebung2`.
.Basisdaten
.Basisdaten der Collection `unicorns`
[source,javascript]
----
{_id: ObjectId("5cc6e5d94249f49a59ac4000"), name: "Horny", dob: new Date(1992,2,13,7,47), loves: ["carrot","papaya"], weight: 600, gender: "m", vampires: 63},
......@@ -735,15 +735,14 @@ In dieser Aufgabe sollen Sie die verschiedenen Varianten kennenlernen.
Weiterführende Informationen zu dieser Aufgabe finden Sie auch in https://github.com/karlseguin/the-little-mongodb-book/blob/master/en/mongodb.markdown#chapter-4---data-modeling[Data Modeling] von The Little MongoDB Book.
.Daten
.Daten der Collection `employees`
[source,javascript]
----
db.employees.insertMany([
{_id: ObjectId("4d85c7039ab0fd70a117d730"), name: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d731"), name: "Duncan", manager: ObjectId("4d85c7039ab0fd70a117d730")},
{_id: ObjectId("4d85c7039ab0fd70a117d732"), name: "Moneo", manager: ObjectId("4d85c7039ab0fd70a117d730")},
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")]},
{_id: ObjectId("4d85c7039ab0fd70a117d734"), name: "Ghanima", family: {mother: "Chani", father: "Paul", brother: ObjectId("4d85c7039ab0fd70a117d730")}}
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")]}
])
----
......@@ -771,27 +770,13 @@ db.employees.findOne({_id: db.employees.find({name:"Moneo"})[0].manager})
----
=====
endif::exercise_solution[]
ifdef::blubby[]
. Finden Sie die Kinder von *Chani*.
// aus einer früheren Aufgabe?!
ifdef::exercise_solution[]
+
[example,title=""]
=====
.Kinder von *Chani*
[source, javascript]
----
db.employees.find({'family.mother': "Chani"})
=====
endif::exercise_solution[]
endif::blubby[]
[id='mongodb-joins-graphlookup']
==== Aufgabe {ex_number}{counter:subtopic}: Joins mit `$graphLookup` Operator
In dieser Aufgabe verwenden wir die https://docs.mongodb.com/manual/aggregation/[Aggregation Pipeline] und den https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/[`$graphLookup`] Operator.
.Daten
.Daten der Collection `employees`
[source,javascript]
----
{_id: ObjectId("4d85c7039ab0fd70a117d730"), name: "Leto"},
......@@ -830,7 +815,10 @@ db.employees.aggregate([
{ $match: { "name":"Moneo"} },
{ $project: { _id:0, name:1, manager:1, managerDocs:1 } }
])
----
.Resultat der Abfrage
[source, javascript]
----
{ "name" : "Moneo", "manager" : "Leto", "managerDocs" : [ { "_id" : ObjectId("4d85c7039ab0fd70a117d730"), "name" : "Leto" } ] }
----
=====
......@@ -841,30 +829,160 @@ endif::exercise_solution[]
Finden Sie eine Möglichkeit einen Join mittels https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/[`$lookup`] Operator durchzuführen?
Welche Daten passen dazu besser, die von <<mongodb-joins-manual>> oder von <<mongodb-joins-graphlookup>>
.[#lookup-manager-moneo]#Q{counter:query_number} Manager von *Moneo*#
Erstellen Sie eine Abfrage um den Manager von *Moneo* anzuzeigen.
.[#lookup-manager-moneo-which-data]#Q{counter:query_number} Passendes DataSet#
Welche Daten passen besser zu einer einfachen `$lookup` Abfrage, die von <<mongodb-joins-manual>> oder von <<mongodb-joins-graphlookup>>?
ifndef::exercise_solution[]
[example,title=""]
=====
{nbsp}
{nbsp}
=====
endif::exercise_solution[]
ifdef::exercise_solution[]
[example,title=""]
=====
Die Daten der Aufgabe <<mongodb-joins-graphlookup>> passen gut für diese einfache Join Abfrage über verschiedene Collections.
=====
endif::exercise_solution[]
{nbsp}
.[#lookup-manager-moneo]#Q{counter:query_number} Manager von *Moneo* ermitteln#
Erstellen Sie eine Abfrage um den Manager von *Moneo* anzuzeigen unter Verwendung von `localField` und `foreignField`.
.Daten der Collection `employees`
[source,javascript]
----
{_id: ObjectId("4d85c7039ab0fd70a117d730"), name: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d731"), name: "Duncan", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d732"), name: "Moneo", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: ["Leto", "Moneo"] }
----
[example,title=""]
=====
.Manager von *Moneo* mit einfachem `$lookup` Aggregat
ifdef::exercise_solution[]
[source,javascript]
----
db.employees.aggregate({
$lookup: {
from: "employees",
localField: "manager",
foreignField: "name",
as: "managers"
}
}, {
$match: {
"name": "Moneo"
}
}, {
$project: {
_id: 0,
manager: 0,
managers: {
_id: 0,
manager: 0
}
}
})
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Abfrage
ifdef::exercise_solution[]
[source, javascript]
----
{ "name" : "Moneo", "managers" : [ { "name" : "Leto" } ] }
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
.[#lookup-manager-moneo]#Q{counter:query_number} Manager von *Moneo* über verschiedene Collections ermitteln#
Erstellen Sie eine Abfrage um den Manager von *Moneo* anzuzeigen wenn die Daten in zwei unterschiedlichen Collections abgelegt sind.
.Daten der beiden Collections
[source,javascript]
----
db.employees.insertMany([
{_id: ObjectId("4d85c7039ab0fd70a117d731"), name: "Duncan", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d732"), name: "Moneo", manager: "Leto"},
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: "Siona", manager: ["Leto", "Moneo"]}
])
db.managers.insertMany([
{_id: ObjectId("4d85c7039ab0fd70a117d740"), name: "Leto", department: "Sales"},
{_id: ObjectId("4d85c7039ab0fd70a117d741"), name: "Moneo", department: "Research"}
])
----
[example,title=""]
=====
.Manager von *Moneo* mit `$lookup`
[source, subs="attributes", javascript]
ifdef::exercise_solution[]
[source, javascript]
----
tbd.
db.employees.aggregate({
$lookup: {
from: "managers",
localField: "manager",
foreignField: "name",
as: "managers"
}
}, {
$match: {
"name": "Moneo"
}
}, {
$project: {
_id: 0,
manager: 0,
managers: {
_id: 0
}
}
})
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Abfrage
ifdef::exercise_solution[]
[source, javascript]
----
{ "name" : "Duncan", "managers" : [ { "name" : "Leto", "department" : "Sales" } ] }
{ "name" : "Moneo", "managers" : [ { "name" : "Leto", "department" : "Sales" } ] }
{ "name" : "Siona", "managers" : [ { "name" : "Leto", "department" : "Sales" }, { "name" : "Moneo", "department" : "Research" } ] }
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
include::{exercises_dir}MongodbShardingScalingOut.asc[]
......
......@@ -128,9 +128,10 @@ Wählen Sie einen passenden Shardkey und begründen Sie ihre Wahl.
=====
.Ausgewählter *Shardkey* mit Begründung
ifdef::exercise_solution[]
`_id`:: Weil...
`name`:: Weil...
`state`:: Weil...
`_id`:: Numerische Werte eignen sich gut für eine gleichmässige Verteilung.
`name`:: Eignet sich gut für Datasets mit grosser Variation wie in diesem Fall.
Kommen jedoch in einem Sprachraum gewisse Wortanfänge häufiger vor, verteilen sich die Chunks nicht so gut.
`state`:: Sieht nach einer Gruppierung aus welche nicht zwingend gleichmässig verteilt sein muss.
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
......@@ -337,6 +338,44 @@ mongos> sh.help()
+
[example,title=""]
=====
.Aktuellen Shard Status anzeigen
ifdef::exercise_solution[]
[source%autofit,javascript]
----
sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ec2a5ebb4a8b473ab0cd507")
}
shards:
active mongoses:
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
+
[example,title=""]
=====
.Shard Instanzen zuweisen
ifdef::exercise_solution[]
[source%autofit,javascript]
......@@ -351,14 +390,34 @@ sh.addShard('shard2:31002')
...
sh.addShard('shard3:31003')
...
ifdef::blubby[]
sh.addShard('dataset/shard1:31001,shard2:31002,shard3:31003')
{
"shardAdded" : "dataset",
"ok" : 1,
...
}
endif::blubby[]
----
.Anzeige des aktuellen Shard Status
[source%autofit,javascript]
----
sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ec2a5ebb4a8b473ab0cd507")
}
shards:
{ "_id" : "shard0000", "host" : "shard1:31001", "state" : 1 }
{ "_id" : "shard0001", "host" : "shard2:31002", "state" : 1 }
{ "_id" : "shard0002", "host" : "shard3:31003", "state" : 1 }
active mongoses:
"4.2.6" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
----
endif::exercise_solution[]
ifndef::exercise_solution[]
......@@ -417,6 +476,47 @@ ifndef::exercise_solution[]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
.. Anpassen der Chunkgrösse
+
Damit die Daten über die Shard Instanzen wie gewünscht verteilt werden muss die voreingestellte Chunkgrösse verkleinert werden.
_The default chunk size for a sharded cluster is 64 megabytes_ (https://docs.mongodb.com/manual/core/sharding-data-partitioning/#chunk-size).
+
[example,title=""]
=====
.Einstieg über den Shardserver (`mongos`)
ifdef::exercise_solution[]
[source,bash]
----
docker-compose --file Helpers/docker-compose.yml --project-name dataeng \
--project-directory . run mongoterm mongo --host shardserver:32000
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
+
[example,title=""]
=====
.Chunkgrösse anpassen
ifdef::exercise_solution[]
[source%autofit,javascript]
----
use config
db.settings.save( { _id:"chunksize", value: 4 } )
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "chunksize" })
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
+
......@@ -432,7 +532,7 @@ sh.status()
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ea75de563f1b4284efd972e")
"clusterId" : ObjectId("5ec2a5ebb4a8b473ab0cd507")
}
shards:
{ "_id" : "shard0000", "host" : "shard1:31001", "state" : 1 }
......@@ -450,14 +550,21 @@ sh.status()
No recent migrations
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
{ "_id" : "test", "primary" : "shard0001", "partitioned" : true, "version" : { "uuid" : UUID("69112054-c1f7-401e-8252-b40286aca2f2"), "lastMod" : 1 } }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
shard0000 1