Signed-off-by: Jannis <jannis@edu.tbz.ch>
This commit is contained in:
Jannis 2025-02-19 18:52:20 +00:00
commit 3cc4ae5699
28 changed files with 1109 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

17
Feldmann.Jannis.json Normal file
View file

@ -0,0 +1,17 @@
[
{
"_id": {
"$oid": "67b48eca0608f20a258e2013"
},
"name": "Jannis Feldmann",
"adresse": "Giessenstrasse 12c",
"plz": 8608,
"ort": "Bubikon",
"geburtsdatum": "2000-08-15T00:00:00Z",
"email": "jannis@epilogue.team",
"hobbies": ["Programmieren", "Sport", "Musik"],
"letztesLogin": {
"$date": "2024-02-18T14:45:00.000Z"
}
}
]

15
README.md Normal file
View file

@ -0,0 +1,15 @@
# KN01
[KN01](KN01/readme.md)
# KN02
[KN02](KN02/readme.md)
# KN03
[KN03](KN03/readme.md)
# KN04
[KN04](KN04/readme.md)
# KN05
[KN05](KN05/readme.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

115
aggregation_1.js Normal file
View file

@ -0,0 +1,115 @@
print("Anspruchsvolle Shooter-Spiele (mit separaten $match Stages):");
db.spiele
.aggregate([
{ $match: { genre: "Tactical Shooter" } },
{ $match: { schwierigkeitsgrad: "Hoch" } },
])
.forEach(printjson);
print("\nSpieler Performance Übersicht:");
db.spieler
.aggregate([
{
$match: {
gesamtpunktzahl: { $gt: 1000 },
},
},
{
$project: {
_id: 0,
username: 1,
performance_metrics: {
punktzahl: "$gesamtpunktzahl",
durchschnittliche_kd: {
$avg: "$spielstatistiken.k_d_ratio",
},
gesamt_spielzeit: {
$sum: "$spielstatistiken.spielzeit_minuten",
},
},
},
},
{
$sort: {
"performance_metrics.punktzahl": -1,
},
},
])
.forEach(printjson);
print("\nGesamtstatistiken über alle Spieler:");
db.spieler
.aggregate([
{
$group: {
_id: null,
total_players: { $sum: 1 },
gesamtpunktzahl: { $sum: "$gesamtpunktzahl" },
durchschnittspunktzahl: { $avg: "$gesamtpunktzahl" },
},
},
])
.forEach(printjson);
print("\nAchievement-Statistiken nach Schwierigkeitsgrad:");
db.achievements
.aggregate([
{
$group: {
_id: "$schwierigkeit",
anzahl_achievements: { $sum: 1 },
durchschnittspunkte: { $avg: "$punktewert" },
gesamtpunkte: { $sum: "$punktewert" },
achievements: {
$push: {
name: "$name",
punktewert: "$punktewert",
},
},
},
},
{
$sort: {
durchschnittspunkte: -1,
},
},
])
.forEach(printjson);
print("\nDurchschnittliche Leistung pro Spiel:");
db.spieler
.aggregate([
{ $unwind: "$spielstatistiken" },
{
$group: {
_id: "$spielstatistiken.spiel_id",
anzahl_spieler: { $sum: 1 },
durchschnitt_kd: { $avg: "$spielstatistiken.k_d_ratio" },
gesamt_siege: { $sum: "$spielstatistiken.siege" },
gesamt_niederlagen: { $sum: "$spielstatistiken.niederlagen" },
durchschnitt_spielzeit: { $avg: "$spielstatistiken.spielzeit_minuten" },
},
},
{
$lookup: {
from: "spiele",
localField: "_id",
foreignField: "_id",
as: "spielinfo",
},
},
{
$project: {
_id: 0,
spiel: { $arrayElemAt: ["$spielinfo.spielname", 0] },
statistiken: {
spieler: "$anzahl_spieler",
kd_ratio: { $round: ["$durchschnitt_kd", 2] },
siege: "$gesamt_siege",
niederlagen: "$gesamt_niederlagen",
avg_spielzeit: { $round: ["$durchschnitt_spielzeit", 0] },
},
},
},
])
.forEach(printjson);

51
cloud-init.yml Normal file
View file

@ -0,0 +1,51 @@
#cloud-config
users:
- name: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, admin
home: /home/ubuntu
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCPIIO8uY8oWIihDv0tCAbX6toyG1RYkaLZyfGD1L+I07K4CnwAVBSU+81vw3Yv5sN9tj2Ccve9kzEeCNMld2mDP/Tt7edkx2MCToVfVx+njqwY/XbMY9bfdRKJLhIoLavuVNLnnkSIXdtlGr3JF71hPHzBDMEo64ofPCQ8hPsGxL1u3efb12jcWcRhudKtv7Qh6cVE47Zj4xImfi6VlLqwzcKZ5oCqR/z1hLLL+/pS3eM5Qsor5wmAqNfH4+z5eE+pOkFm7a0Nkygv9jwXIqtJzFGKYDe6ciBD04pEovdvY0FTyiv2vksQOVgjtu2faG2Iv1HOG0JktCIwJ49OEgjT teacher-key
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKgdN/WkRYNDPLa06pBFByEMfkT+ic8XjL+WG4VcXVtN jannisfeldmann@MacBook-Air-von-Jannis.local
ssh_pwauth: false
disable_root: false
package_update: true
packages:
- unzip
- gnupg
- curl
write_files:
- path: /home/ubuntu/mongodconfupdate.sh
content: |
sudo sed -i 's/#security:/security:\n authorization: enabled/g' /etc/mongod.conf
- path: /home/ubuntu/mongodbuser.txt
content: |
use admin;
db.createUser(
{
user: "admin",
pwd: "MyPassword.42",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "root", db: "admin" }
]
}
);
runcmd:
- curl -fsSL https://pgp.mongodb.com/server-6.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg --dearmor
- echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
- sudo apt-get update -y
- sudo apt-get install -y mongodb-org
- sudo sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mongod.conf
- sudo chmod +x /home/ubuntu/mongodconfupdate.sh
- sudo /home/ubuntu/mongodconfupdate.sh
- sudo systemctl enable mongod
- sudo systemctl start mongod
- sleep 10
- mongosh < /home/ubuntu/mongodbuser.txt
- sudo systemctl restart mongod

153
create_data.js Normal file
View file

@ -0,0 +1,153 @@
const valorantId = new ObjectId();
const csgoId = new ObjectId();
const apexId = new ObjectId();
db.spiele.insertMany([
{
_id: valorantId,
spielname: "Valorant",
genre: "Tactical Shooter",
schwierigkeitsgrad: "Hoch",
},
{
_id: csgoId,
spielname: "CS:GO",
genre: "Tactical Shooter",
schwierigkeitsgrad: "Hoch",
},
{
_id: apexId,
spielname: "Apex Legends",
genre: "Battle Royale",
schwierigkeitsgrad: "Mittel",
},
]);
const player1Id = new ObjectId();
const player2Id = new ObjectId();
const player3Id = new ObjectId();
const player4Id = new ObjectId();
db.spieler.insertOne({
_id: player1Id,
username: "ProGamer123",
email: "progamer@gaming.com",
registrierungsdatum: new Date("2024-01-15"),
gesamtpunktzahl: 2500,
rang: 1,
spielstatistiken: [
{
spiel_id: valorantId,
punktzahl: 1500,
siege: 42,
niederlagen: 18,
k_d_ratio: 1.8,
spielzeit_minuten: 1800,
letztes_spiel: new Date("2024-02-15"),
},
{
spiel_id: csgoId,
punktzahl: 1000,
siege: 35,
niederlagen: 25,
k_d_ratio: 1.5,
spielzeit_minuten: 1500,
letztes_spiel: new Date("2024-02-10"),
},
],
});
db.spieler.insertMany([
{
_id: player2Id,
username: "GameMaster99",
email: "master99@gaming.com",
registrierungsdatum: new Date("2024-01-20"),
gesamtpunktzahl: 2200,
rang: 2,
spielstatistiken: [
{
spiel_id: valorantId,
punktzahl: 1200,
siege: 38,
niederlagen: 22,
k_d_ratio: 1.6,
spielzeit_minuten: 1600,
letztes_spiel: new Date("2024-02-14"),
},
],
},
{
_id: player3Id,
username: "NoobSlayer",
email: "slayer@gaming.com",
registrierungsdatum: new Date("2024-02-01"),
gesamtpunktzahl: 1800,
rang: 3,
spielstatistiken: [
{
spiel_id: apexId,
punktzahl: 1800,
siege: 25,
niederlagen: 15,
k_d_ratio: 2.1,
spielzeit_minuten: 900,
letztes_spiel: new Date("2024-02-16"),
},
],
},
]);
const achievement1Id = new ObjectId();
const achievement2Id = new ObjectId();
const achievement3Id = new ObjectId();
db.achievements.insertMany([
{
_id: achievement1Id,
name: "Flawless Victory",
beschreibung: "Gewinne ein Spiel ohne zu sterben",
punktewert: 500,
schwierigkeit: "Sehr Hoch",
errungen_von: [
{
spieler_id: player1Id,
erreicht_am: new Date("2024-02-01"),
},
],
},
{
_id: achievement2Id,
name: "First Blood",
beschreibung: "Erziele den ersten Kill in 50 Spielen",
punktewert: 200,
schwierigkeit: "Mittel",
errungen_von: [
{
spieler_id: player1Id,
erreicht_am: new Date("2024-01-20"),
},
{
spieler_id: player2Id,
erreicht_am: new Date("2024-02-05"),
},
],
},
{
_id: achievement3Id,
name: "Veteran",
beschreibung: "Spiele 100 Stunden",
punktewert: 300,
schwierigkeit: "Niedrig",
errungen_von: [
{
spieler_id: player1Id,
erreicht_am: new Date("2024-02-10"),
},
{
spieler_id: player3Id,
erreicht_am: new Date("2024-02-15"),
},
],
},
]);

288
db.drawio Normal file
View file

@ -0,0 +1,288 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:135.0) Gecko/20100101 Firefox/135.0" version="26.0.14">
<diagram name="Seite-1" id="cBTbvHJHdlLuG1iU_9py">
<mxGraphModel dx="1761" dy="704" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="p0t2gclCdJraA5zFe3de-1" value="Achievement Collection" style="whiteSpace=wrap;strokeWidth=2;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="-20" y="480" width="1536" height="387" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-2" value="Achievement Dokument" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="555" y="46" width="230" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-3" value="_id: ObjectId" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="43" y="175" width="155" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-4" value="name: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="248" y="175" width="150" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-5" value="beschreibung: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="448" y="175" width="206" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-6" value="punktewert: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="704" y="175" width="173" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-7" value="schwierigkeit: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="927" y="175" width="206" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-8" value="errungen_von: Array" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="1183" y="175" width="207" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-9" value="spieler_id: ObjectId" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="614" y="304" width="203" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-10" value="erreicht_am: date" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-1" vertex="1">
<mxGeometry x="1314" y="304" width="191" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-11" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.74;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-2" target="p0t2gclCdJraA5zFe3de-3" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="120" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-12" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.89;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-2" target="p0t2gclCdJraA5zFe3de-4" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="323" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-13" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.28;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-2" target="p0t2gclCdJraA5zFe3de-5" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="551" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-14" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.72;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-2" target="p0t2gclCdJraA5zFe3de-6" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="790" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-15" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.87;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-2" target="p0t2gclCdJraA5zFe3de-7" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1030" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-16" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.71;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-2" target="p0t2gclCdJraA5zFe3de-8" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1286" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-17" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.71;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-8" target="p0t2gclCdJraA5zFe3de-9" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="715" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-18" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.75;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-1" source="p0t2gclCdJraA5zFe3de-8" target="p0t2gclCdJraA5zFe3de-10" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1409" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-19" value="Spiel Collection" style="whiteSpace=wrap;strokeWidth=2;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="1566" y="545" width="954" height="258" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-20" value="Spiel Dokument" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-19" vertex="1">
<mxGeometry x="362" y="46" width="172" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-21" value="_id: ObjectId" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-19" vertex="1">
<mxGeometry x="43" y="175" width="155" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-22" value="spielname: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-19" vertex="1">
<mxGeometry x="248" y="175" width="184" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-23" value="genre: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-19" vertex="1">
<mxGeometry x="481" y="175" width="152" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-24" value="schwierigkeitsgrad: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-19" vertex="1">
<mxGeometry x="683" y="175" width="244" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-25" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.8;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-19" source="p0t2gclCdJraA5zFe3de-20" target="p0t2gclCdJraA5zFe3de-21" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="120" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-26" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.24;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-19" source="p0t2gclCdJraA5zFe3de-20" target="p0t2gclCdJraA5zFe3de-22" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="339" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-27" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.77;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-19" source="p0t2gclCdJraA5zFe3de-20" target="p0t2gclCdJraA5zFe3de-23" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="557" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-28" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.78;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-19" source="p0t2gclCdJraA5zFe3de-20" target="p0t2gclCdJraA5zFe3de-24" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="805" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-29" value="Spieler Collection" style="whiteSpace=wrap;strokeWidth=2;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="2570" y="480" width="2011" height="387" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-30" value="Spieler Dokument" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="376" y="46" width="187" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-31" value="_id: ObjectId" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="43" y="175" width="155" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-32" value="username: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="248" y="175" width="180" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-33" value="email: string" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="478" y="175" width="151" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-34" value="registrierungsdatum: date" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="679" y="175" width="247" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-35" value="gesamtpunktzahl: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="976" y="175" width="212" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-36" value="rang: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="1238" y="175" width="122" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-37" value="spielstatistiken: Array" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="1409" y="175" width="217" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-38" value="spiel_id: ObjectId" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="424" y="304" width="188" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-39" value="punktzahl: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="662" y="304" width="161" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-40" value="siege: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="873" y="304" width="127" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-41" value="niederlagen: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="1074" y="304" width="175" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-42" value="k_d_ratio: float" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="1299" y="304" width="173" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-43" value="spielzeit_minuten: int" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="1521" y="304" width="219" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-44" value="letztes_spiel: date" style="whiteSpace=wrap;strokeWidth=2;" parent="p0t2gclCdJraA5zFe3de-29" vertex="1">
<mxGeometry x="1790" y="304" width="194" height="54" as="geometry" />
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-45" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.81;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-31" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="120" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-46" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.2;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-32" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="338" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-47" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.69;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-33" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="553" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-48" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.83;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-34" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="802" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-49" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.67;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-35" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1082" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-50" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.63;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-36" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1299" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-51" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.6;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-30" target="p0t2gclCdJraA5zFe3de-37" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1518" y="137" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-52" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.62;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-38" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="518" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-53" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.66;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-39" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="742" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-54" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.71;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-40" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="936" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-55" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0;exitY=0.85;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-41" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1161" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-56" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.25;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-42" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1385" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-57" value="" style="curved=1;startArrow=none;endArrow=block;exitX=0.72;exitY=0.99;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-43" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1630" y="266" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="p0t2gclCdJraA5zFe3de-58" value="" style="curved=1;startArrow=none;endArrow=block;exitX=1;exitY=0.84;entryX=0.5;entryY=-0.01;rounded=0;" parent="p0t2gclCdJraA5zFe3de-29" source="p0t2gclCdJraA5zFe3de-37" target="p0t2gclCdJraA5zFe3de-44" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1887" y="266" />
</Array>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

5
db.js Normal file
View file

@ -0,0 +1,5 @@
db.createCollection("spieler");
db.createCollection("spiele");
db.createCollection("achievements");

BIN
db.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

3
delete_data_1.js Normal file
View file

@ -0,0 +1,3 @@
db.spieler.drop();
db.spiele.drop();
db.achievements.drop();

9
delete_data_2.js Normal file
View file

@ -0,0 +1,9 @@
const playerToDeleteId = new ObjectId("65c4d2e6b3c72d3c45a77777");
const achievement1ToDeleteId = new ObjectId("65c4d2e6b3c72d3c45a88888");
const achievement2ToDeleteId = new ObjectId("65c4d2e6b3c72d3c45a99999");
db.spieler.deleteOne({ _id: playerToDeleteId });
db.achievements.deleteMany({
$or: [{ _id: achievement1ToDeleteId }, { _id: achievement2ToDeleteId }],
});

213
join_aggregation.js Normal file
View file

@ -0,0 +1,213 @@
print("Spieler mit Details ihrer Achievements:");
db.spieler
.aggregate([
{
$lookup: {
from: "achievements",
let: { spielerId: "$_id" },
pipeline: [
{
$match: {
$expr: {
$in: ["$$spielerId", "$errungen_von.spieler_id"],
},
},
},
],
as: "erreichte_achievements",
},
},
{
$project: {
username: 1,
gesamtpunktzahl: 1,
achievements: {
$map: {
input: "$erreichte_achievements",
as: "achievement",
in: {
name: "$$achievement.name",
punktewert: "$$achievement.punktewert",
schwierigkeit: "$$achievement.schwierigkeit",
},
},
},
},
},
])
.forEach(printjson);
print("\nDetailierte Spieleranalyse mit Spiel- und Achievement-Informationen:");
db.spieler
.aggregate([
{ $unwind: "$spielstatistiken" },
{
$lookup: {
from: "spiele",
localField: "spielstatistiken.spiel_id",
foreignField: "_id",
as: "spiel_details",
},
},
{
$lookup: {
from: "achievements",
let: { spielerId: "$_id" },
pipeline: [
{
$match: {
$expr: {
$in: ["$$spielerId", "$errungen_von.spieler_id"],
},
},
},
],
as: "achievements",
},
},
{
$project: {
_id: 0,
spieler: "$username",
spiel: { $arrayElemAt: ["$spiel_details.spielname", 0] },
genre: { $arrayElemAt: ["$spiel_details.genre", 0] },
leistung: {
siege: "$spielstatistiken.siege",
niederlagen: "$spielstatistiken.niederlagen",
k_d_ratio: "$spielstatistiken.k_d_ratio",
spielzeit: "$spielstatistiken.spielzeit_minuten",
},
achievements: {
anzahl: { $size: "$achievements" },
gesamtpunkte: { $sum: "$achievements.punktewert" },
liste: "$achievements.name",
},
},
},
{
$match: {
"leistung.k_d_ratio": { $gt: 1.5 },
},
},
{
$sort: {
"leistung.k_d_ratio": -1,
},
},
])
.forEach(printjson);
print("\nSpiel-Achievement-Analyse:");
db.spiele
.aggregate([
{
$lookup: {
from: "achievements",
let: { spielId: "$_id" },
pipeline: [
{
$match: {
$expr: {
$gt: [{ $size: "$errungen_von" }, 1],
},
},
},
],
as: "spiel_achievements",
},
},
{
$lookup: {
from: "spieler",
let: { spielId: "$_id" },
pipeline: [
{ $unwind: "$spielstatistiken" },
{
$match: {
$expr: {
$eq: ["$spielstatistiken.spiel_id", "$$spielId"],
},
},
},
],
as: "spieler_stats",
},
},
{
$project: {
spielname: 1,
genre: 1,
schwierigkeitsgrad: 1,
statistiken: {
aktive_spieler: { $size: "$spieler_stats" },
durchschnitt_kd: {
$avg: "$spieler_stats.spielstatistiken.k_d_ratio",
},
gesamt_spielzeit: {
$sum: "$spieler_stats.spielstatistiken.spielzeit_minuten",
},
achievements: {
anzahl: { $size: "$spiel_achievements" },
schwierigkeitsverteilung: {
$reduce: {
input: "$spiel_achievements",
initialValue: { einfach: 0, mittel: 0, schwer: 0 },
in: {
einfach: {
$add: [
"$$value.einfach",
{
$cond: [
{ $eq: ["$$this.schwierigkeit", "Niedrig"] },
1,
0,
],
},
],
},
mittel: {
$add: [
"$$value.mittel",
{
$cond: [
{ $eq: ["$$this.schwierigkeit", "Mittel"] },
1,
0,
],
},
],
},
schwer: {
$add: [
"$$value.schwer",
{
$cond: [
{ $eq: ["$$this.schwierigkeit", "Sehr Hoch"] },
1,
0,
],
},
],
},
},
},
},
},
},
},
},
{
$sort: {
"statistiken.aktive_spieler": -1,
},
},
])
.forEach(printjson);

44
read_data.js Normal file
View file

@ -0,0 +1,44 @@
print("Neue Spieler seit 15. Januar 2024:");
db.spieler.find(
{ registrierungsdatum: { $gt: new Date("2024-01-15") } },
{ username: 1, registrierungsdatum: 1 }
).forEach(printjson);
print("\nTop Performer (hohe Punktzahl oder viele Siege):");
db.spieler.find({
$or: [
{ gesamtpunktzahl: { $gt: 2000 } },
{ "spielstatistiken.siege": { $gt: 40 } }
]
}).forEach(printjson);
print("\nAnspruchsvolle Shooter-Spiele:");
db.spiele.find({
$and: [
{ genre: "Tactical Shooter" },
{ schwierigkeitsgrad: "Hoch" }
]
}).forEach(printjson);
print("\nSpieler mit 'Pro' oder 'Game' im Namen:");
db.spieler.find(
{ username: { $regex: /Pro|Game/i } },
{ _id: 0, username: 1, gesamtpunktzahl: 1 }
).forEach(printjson);
print("\nBegehrte Achievements:");
db.achievements.find({
punktewert: { $gt: 200 },
"errungen_von.1": { $exists: true }
}).forEach(printjson);
print("\nValorant Spielerstatistiken:");
db.spieler.find(
{ "spielstatistiken.punktzahl": { $gt: 1000 } },
{
username: 1,
"spielstatistiken.$": 1
}
).forEach(printjson);

18
readme.md Normal file
View file

@ -0,0 +1,18 @@
# A: Konzeptionelles Datenmodell
![alt text](<Screenshot 2025-02-18 at 14.56.34.png>)
# B: Logisches Modell für MongoDB
![alt text](<Unbenanntes Diagramm.drawio.png>)
Spiele werden als eigene collection gespeichert, weil sie von vielen Spielern referenziert werden und selten geändert werden. Das vermeidet auch duplikate.
Achievements werden häufig nach allen Spielern gefiltert, die sie erreicht haben.
"errungen_von" speichert, welche Spieler ein Achievement erreicht haben.
# C: Anwendung des Schemas in MongoDB
[db.js](db.js)

106
unter_dokumente.js Normal file
View file

@ -0,0 +1,106 @@
print("Spielstatistiken aller Spieler:");
db.spieler
.find({}, { _id: 0, username: 1, spielstatistiken: 1 })
.forEach(printjson);
print("\nSpieler mit K/D-Ratio über 1.8 in irgendeinem Spiel:");
db.spieler
.find(
{
"spielstatistiken.k_d_ratio": { $gt: 1.8 },
},
{
username: 1,
spielstatistiken: {
$filter: {
input: "$spielstatistiken",
as: "stat",
cond: { $gt: ["$$stat.k_d_ratio", 1.8] },
},
},
}
)
.forEach(printjson);
print("\nVerflachte Spielerstatistiken:");
db.spieler
.aggregate([
{ $unwind: "$spielstatistiken" },
{
$match: {
"spielstatistiken.spielzeit_minuten": { $gt: 1000 },
},
},
{
$project: {
_id: 0,
spieler: "$username",
spiel_id: "$spielstatistiken.spiel_id",
statistiken: {
siege: "$spielstatistiken.siege",
niederlagen: "$spielstatistiken.niederlagen",
k_d_ratio: "$spielstatistiken.k_d_ratio",
spielzeit: "$spielstatistiken.spielzeit_minuten",
letztes_spiel: "$spielstatistiken.letztes_spiel",
},
},
},
{
$sort: {
"statistiken.k_d_ratio": -1,
},
},
])
.forEach(printjson);
print("\nDurchschnittliche Statistiken pro Spiel:");
db.spieler
.aggregate([
{ $unwind: "$spielstatistiken" },
{
$group: {
_id: "$spielstatistiken.spiel_id",
anzahl_spieler: { $sum: 1 },
durchschnitt_kd: { $avg: "$spielstatistiken.k_d_ratio" },
gesamt_spielzeit: { $sum: "$spielstatistiken.spielzeit_minuten" },
gesamt_siege: { $sum: "$spielstatistiken.siege" },
gesamt_niederlagen: { $sum: "$spielstatistiken.niederlagen" },
},
},
{
$lookup: {
from: "spiele",
localField: "_id",
foreignField: "_id",
as: "spiel_info",
},
},
{
$project: {
_id: 0,
spiel: { $arrayElemAt: ["$spiel_info.spielname", 0] },
statistiken: {
spieler: "$anzahl_spieler",
avg_kd: { $round: ["$durchschnitt_kd", 2] },
spielzeit_stunden: {
$round: [{ $divide: ["$gesamt_spielzeit", 60] }, 1],
},
siege: "$gesamt_siege",
niederlagen: "$gesamt_niederlagen",
},
},
},
{
$sort: {
"statistiken.spieler": -1,
},
},
])
.forEach(printjson);

50
update_data.js Normal file
View file

@ -0,0 +1,50 @@
const playerToUpdateId = new ObjectId("65c4d2e6b3c72d3c45a77777");
db.spieler.updateOne(
{ _id: playerToUpdateId },
{
$set: {
gesamtpunktzahl: 3000,
rang: 1,
},
$push: {
spielstatistiken: {
spiel_id: new ObjectId("65c4d2e6b3c72d3c45a66666"),
punktzahl: 500,
siege: 15,
niederlagen: 5,
k_d_ratio: 2.0,
spielzeit_minuten: 300,
letztes_spiel: new Date(),
},
},
}
);
db.spiele.updateMany(
{
$or: [{ genre: "Tactical Shooter" }, { genre: "Battle Royale" }],
},
{
$set: {
version: "2.0",
letztes_update: new Date(),
},
}
);
db.achievements.replaceOne(
{ name: "First Blood" },
{
name: "First Blood Pro",
beschreibung: "Erziele den ersten Kill in 100 Spielen",
punktewert: 500,
schwierigkeit: "Sehr Hoch",
errungen_von: [],
anforderungen: {
anzahl_spiele: 100,
zeitlimit_tage: 30,
mindest_kdRatio: 1.5,
},
}
);

22
user_creation.js Normal file
View file

@ -0,0 +1,22 @@
use gaming
db.createUser({
user: "readOnlyUser",
pwd: "readOnly123",
roles: [
{ role: "read", db: "gaming" }
]
})
use admin
db.createUser({
user: "readWriteUser",
pwd: "readWrite123",
roles: [
{ role: "readWrite", db: "gaming" }
]
})
use admin
db.system.users.find({}, {user: 1, db: 1, roles: 1})