SlideShare ist ein Scribd-Unternehmen logo
MongoDB für
Java-Programmierer
Uwe Seiler
uweseiler
About me

Big Data Nerd

Hadoop Trainer MongoDB Author

Photography Enthusiast

Travelpirate
About us
is a bunch of…

Big Data Nerds

Agile Ninjas

Continuous Delivery Gurus

Join us!
Enterprise Java Specialists Performance Geeks
Agenda
•

Buzzword Bingo

•

Überblick über MongoDB

•

Datenmanipulation

•

Indexing

• Konsistenz beim Schreiben und Lesen

von Daten
• Java API & Frameworks
Buzzword Bingo
NoSQL
Klassifizierung von NoSQL
Key-Value Stores
K

V

K

V

K

V

K

1

V

K

Column Stores

V

Graph Databases

1

1
1
1

1
1
1

1
1
1

Document Stores
_id
_id
_id
Big Data
Meine Lieblingsdefinition
Die klassische Definition
•

The 3 V’s of Big Data

Volume Velocity •Variety
«Big Data» != Hadoop
Horizontale
Skalierung
Vertikale Skalierung

RAM
CPU
Storage
Vertikale Skalierung

RAM
CPU
Storage
Vertikale Skalierung

RAM
CPU
Storage
Horizontale Skalierung

RAM
CPU
Storage
Horizontale Skalierung

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage
Horizontale Skalierung
RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage

RAM
CPU
Storage
Das Problem
mit der
Verteilung
Das CAP Theorem
Availability
Jede Anfrage
bekommt eine
Antwort

Consistency
Alle Knoten
haben
jederzeit die
gleichen
Informationen

Partition
Tolerance
Trotz
Knotenausfall
funktioniert
das System
Überblick über NoSQL Systeme

Availability
Jeder Client
kann immer
schreiben und
lesen

C

onsistency

Alle Knoten
haben
jederzeit die
gleichen
Informationen

Partition
Tolerance
Trotz
Knotenausfall
funktioniert
das System
Das Problem
mit der
Konsistenz
ACID

vs.
BASE
ACID vs. BASE

1983

Atomicity RDBMS
Consistency
Isolation
Durability
ACID vs. BASE

ACID ist ein gutes
Konzept, aber es ist
kein in Stein
gemeißeltes Gesetz!
ACID vs. BASE

Basically Available
Soft State
2008

NoSQL

Eventually consistent
ACID vs. BASE
ACID

BASE

-

-

Starke Konsistenz
Isolation
Zwei-Phasen-Commit
Komplexe Entwicklung
Zuverlässiger

Schwache Konsistenz
Verfügbarkeit
"Fire-and-forget"
Leichtere Entwicklung
Schneller
Überblick über MongoDB
MongoDB ist eine …
•

Dokumenten-basierte

•

Open Source

•

Performante

•

Flexible

•

Skalierbare

•

Hochverfügbare

•

Funktionsreiche

…Datenbank
Dokumenten-basierte Datenbank
•

Nicht im Sinne einer Datenbank für PDFoder Worddokumente…
Open Source Datenbank
•

MongoDB ist ein Open Source Projekt

•

Auf GitHub
– https://github.com/mongodb/mongo

•

Steht unter der AGPL Lizenz

•

Gestartet und gesponsert von MongoDB
Inc. (früher: 10gen)

•

Kommerzielle Lizenzen sind verfügbar

•

Jeder darf mitmachen!
– https://jira.mongodb.org
Performance

Datenlokalität

In-Memory
Caching

In-Place
Updates
Flexibles Schema
MongoDB

RDBMS
{

_id :
ObjectId("4c4ba5e5e8aabf3"),
employee_name: "Dunham, Justin",
department : "Marketing",
title : "Product Manager, Web",
report_up: "Neray, Graham",
pay_band: “C",
benefits : [
{ type : "Health",
plan : "PPO Plus" },
{ type :
"Dental",
plan : "Standard" }
]
}
Skalierbarkeit
Auto-Sharding

• Erhöhung der Kapazität wenn nötig
• Ausgelegt für Commodity Hardware
• Funktioniert mit Cloud-Architekturen
Hochverfügbarkeit

• Automatische Replikation und Failover
• Unterstützung für mehrere Datenzentren
• Ausgelegt auf möglichst einfachen Betrieb
• Beständigkeit und Konsistenz der Daten
MongoDB Architektur
Reichhaltige Abfragen
Aggregation Framework
Map/Reduce
MongoDB

Data

Map()
emit(k,v)

Group(k)

Shard 1
Sort(k)
Shard 2

…
Shard
n

Reduce(k, values)

Finalize(k, v)
Geoinformationen
Treiber & Shell
Treiber verfügbar für
die populärsten
Programmiersprachen
und Frameworks

Java

JavaScript

Python

Shell zur Interaktion mit
der Datenbank

Ruby

Perl

Haskell

> db.collection.insert({product:“MongoDB”,
type:“Document Database”})
>
> db.collection.findOne()
{
“_id”
: ObjectId(“5106c1c2fc629bfe52792e86”),
“product”
: “MongoDB”
“type”
: “Document Database”
}
NoSQL Trends
Google Search

LinkedIn Job Skills
MongoDB
Competitor 1
Competitor 2
Competitor 3
Competitor 4
Competitor 5

MongoDB

Competitor 2

Competitor 1

Competitor 4

Competitor 3

All Others

Jaspersoft Big Data Index

Indeed.com Trends
Top Job Trends

Direct Real-Time Downloads
MongoDB
Competitor 1
Competitor 2
Competitor 3

1.HTML 5
2.MongoDB
3.iOS
4.Android
5.Mobile Apps
6.Puppet
7.Hadoop
8.jQuery
9.PaaS
10.Social Media
Datenmanipulation
Terminologie
RDBMS
Tabelle / View
Zeile
Index
Join
Fremdschlüssel
Partition

MongoDB
➜
➜
➜
➜

Collection
Dokument
Index
Eingebettetes
Dokument
➜ Referenziertes
Dokument
➜ Shard
Let’s have a look…
Anlegen einer Datenbank
// Anzeigen aller Datenbanken
> show dbs
digg 0.078125GB
enron 1.49951171875GB
// Wechsel in eine Datenbank
> use blog
// Erneutes Anzeigen aller Datenbanken
> show dbs
digg 0.078125GB
enron 1.49951171875GB
Anlegen einer Collection I
// Anzeigen aller Collections
> show collections
// Einfügen eines Benutzers
> db.user.insert(
{ name : “Sheldon“,
mail : “sheldon@bigbang.com“ }
)

Beim Einfügen erfolgt kein Feedback über
den Erfolg der Operation, Abfrage über:
db.runCommand( { getLastError: 1} )
Anlegen einer Collection II
// Anzeigen aller Collections
> show collections
system.indexes
user
// Anzeigen aller Datenbanken
> show dbs
blog 0.0625GB
digg 0.078125GB
enron 1.49951171875GB

Datenbank und Collection
werden automatisch beim
ersten Insert anlegt.
Lesen aus einer Collection
// Anzeigen des ersten Dokuments
> db.user.findOne()
{
"_id" : ObjectId("516684a32f391f3c2fcb80ed"),
"name" : "Sheldon",
"mail" : "sheldon@bigbang.com"
}
// Alle Dokumente einer Collection anzeigen
> db.user.find()
{
"_id" : ObjectId("516684a32f391f3c2fcb80ed"),
"name" : "Sheldon",
"mail" : "sheldon@bigbang.com"
}
Filtern von Dokumenten
// Filtern von bestimmten Dokumenten
> db.user.find( { name : ”Penny” } )
{
"_id" : ObjectId("5166a9dc2f391f3c2fcb80f1"),
"name" : "Penny",
"mail" : "penny@bigbang.com"
}
// Nur bestimmte Felder anzeigen
> db.user.find( { name : ”Penny” },
{_id: 0, mail : 1} )
{ "mail" : "sheldon@bigbang.com" }
_id
•

_id ist der primäre Schlüssel in MongoDB

•

Index auf _id wird automatisch erzeugt

•

Wenn nicht anders angegeben, handelt es
sich dabei um eine ObjectId

•

_id kann auch selbst beim Einfügen von
Dokumenten vergeben werden, jeder
einzigartige unveränderbare Wert kann
dabei verwendet werden
ObjectId
•

Eine ObjectId ist ein spezieller 12 Byte
Wert

•

Ihre Einzigartigkeit über den gesamten
Cluster ist durch die Zusammensetzung
garantiert:
ObjectId("50804d0bd94ccab2da652599")
|-------------||---------||-----||----------|
ts
mac pid inc
Cursor
// Benutzen eines Cursors für die Dokumente
> var myCursor = db.user.find( )
// Nächstes Dokument holen und Mail anzeigen
> var myDocument =
myCursor.hasNext() ? myCursor.next() : null;
> if (myDocument) { printjson(myDocument.mail); }
// Restliche Dokumente anzeigen
> myCursor.forEach(printjson);

In der Shell werden per Default
20 Dokumente angezeigt.
Logische Verknüpfungen
// Oder-Verknüpfung
> db.user.find(
{$or : [ { name : “Sheldon“ },
{ mail : amy@bigbang.com }
]
})
// Und-Verknüpfung
> db.user.find(
{$and : [ { name : “Sheldon“ },
{ mail : amy@bigbang.com }
]
})
Ergebnismengen anpassen
// Sortieren von Dokumenten
> db.user.find().sort( { name : 1 } ) // Aufsteigend
> db.user.find().sort( { name : -1 } ) // Absteigend
// Ergebnismenge limitieren
> db.user.find().limit(3)
// Ergebnisdokumente überspringen
> db.user.find().skip(2)
// Kombination der Methoden
> db.user.find().skip(2).limit(3)
Update von Dokumenten I
// Update der Mail-Adresse (So bitte nicht!)
> db.user.update( { name : “Sheldon“ },
{ mail : “sheldon@howimetyourmother.com“ }
)
// Anzeige des Updates
db.user.findOne()
{
"_id" : ObjectId("516684a32f391f3c2fcb80ed"),
"mail" : "sheldon@howimetyourmother.com"
}

Aufpassen beim Update von
Dokumenten!
Löschen von Dokumenten
// Löschen des Dokuments
> db.user.remove(
{ mail : “sheldon@howimetyourmother.com“ }
)
// Löschen aller Dokumente
> db.user.remove()
// Löschen von Dokumenten mittels Bedingung
> db.user.remove(
{ mail : /.*mother.com$/ } )
// Löschen nur des ersten passenden Dokuments
> db.user.remove( { mail : /.*.com$/ }, true )
Update von Dokumenten II
// Update der Mail-Adresse (Jetzt aber richtig!)
> db.user.update( { name : “Sheldon“ },
{ $set : {
mail : “sheldon@howimetyourmother.com“
}})
// Anzeige des Updates
db.user.find(name : “Sheldon“)
{
"_id" : ObjectId("5166ba122f391f3c2fcb80f5"),
"mail" : "sheldon@howimetyourmother.com",
"name" : "Sheldon"
}
Hinzufügen zu Arrays
// Hinzufügen eines Arrays
> db.user.update( {name : “Sheldon“ },
{ $set : {enemies :
[ { name : “Wil Wheaton“ },
{ name : “Barry Kripke“ }
]
}})
// Hinzufügen eines Wertes zum Array
> db.user.update( { name : “Sheldon“},
{ $push : {enemies :
{ name : “Leslie Winkle“}
}})
Löschen aus Arrays
// Löschen eines Wertes aus dem Array
> db.user.update( { name : “Sheldon“ },
{$pull : {enemies :
{name : “Barry Kripke“ }
}})
// Löschen des kompletten Feldes
> db.user.update( {name : “Sheldon“},
{$unset : {enemies : 1}}
)
Einfügen eines Subdokuments
// Hinzufügen eines Subdokuments
> db.user.update( { name : “Sheldon“}, {
$set : { mother :{ name : “Mary Cooper“,
residence : “Galveston, Texas“,
religion : “Evangelical Christian“ }}})
{
"_id" : ObjectId("5166cf162f391f3c2fcb80f7"),
"mail" : "sheldon@bigbang.com",
"mother" : {
"name" : "Mary Cooper",
"residence" : "Galveston, Texas",
"religion" : "Evangelical Christian"
},
"name" : "Sheldon"
}
Abfragen auf Subdokumenten
// Abfrage des Namens der Mutter
> db.user.find( { name : “Sheldon“},
{“mother.name“ : 1 } )
{
"_id" : ObjectId("5166cf162f391f3c2fcb80f7"),
"mother" : {
"name" : "Mary Cooper"
}
}

Zusammengesetzte Feldnamen
müssen in “…“ stehen!
Übersicht über alle UpdateOperatoren
Für Felder:
$inc
$rename
$set
$unset
Bitweise:
$bit
Isolation:
$isolated

Für Arrays:
$addToSet
$pop
$pullAll
$pull
$pushAll
$push
$each (Modifier)
$slice (Modifier)
$sort (Modifier)
Dokumentation

Create
http://docs.mongodb.org/manual/core/create/

Read
http://docs.mongodb.org/manual/core/read/

Update
http://docs.mongodb.org/manual/core/update/

Delete
http://docs.mongodb.org/manual/core/delete/
Das Aggregation Framework
•

Wurde eingeführt, um Aggregationen
ohne Map/Reduce berechnen zu können

•

Framework von Methoden & Operatoren
– Deklarativ
– Kein eigener JavaScript-Code mehr nötig
– Framework kann erweitert werden

•

Implementiert in C++
– Overhead der JavaScript-Engine wird vermieden
– Höhere Performance
Aggregation Pipeline
Pipeline
Operator
Pipeline
Operator
Pipeline
Operator

{
document
}

Ergebnis
{
sum: 337
avg: 24,53
min: 2
max : 99
}
Aggregation Pipeline
•

Verarbeitet einen Strom von Dokumenten
– Eingabe ist eine Collection
– Ausgabe ist ein Ergebnisdokument

•

Aneinanderreihung von PipelineOperatoren
– Jede Stufe filtert oder transformiert die Dokumente
– Ausgabedokumente einer Stufe sind die Eingabe-

dokumente der nächsten Stufe
Aufruf
> db.tweets.aggregate(
{ $pipeline_operator_1
{ $pipeline_operator_2
{ $pipeline_operator_3
{ $pipeline_operator_4
...
);

},
},
},
},
Pipeline Operatoren
// Alte Bekannte* // Neue Freunde
$match
$sort
$limit
$skip
* Aus der Abfragefunktionalität

$project
$group
$unwind
Aggregation Framework I
// Collection mit Tweets
{
"_id" : ObjectId("4fb9fb91d066d657de8d6f39"),
"text" : "I can't wait for #BoardwalkEmpire",
"in_reply_to_status_id" : null,
"retweet_count" : null,
"contributors" : null,
"created_at" : "Thu Sep 02 18:11:24 +0000 2010",
…
"user" : {
"friends_count" : 204,
…
"followers_count" : 24,
"id" : 64054560,
…
},
…}
Aggregation Framework II
// Finde die Top-3-Twitterer nach Followern
> db.tweets.aggregate(
{ $project : {name : "$user.name",
follower_count : "$user.followers_count"}},
{ $group : {_id : {name : "$name"},
follower_count : {$max : "$follower_count"}}},
{ $sort : {follower_count : -1}},
{ $limit: 3}
);
Aggregation Framework III
// Finde die Top-3-Links aus Tweets
> db.tweets.aggregate(
{ $project : {_id: 0, inhalt_des_tweets :
"$text", links : "$entities.urls.url" } },
{ $unwind : "$links" },
{ $group : { _id : "$links",
anzahl : {$sum : 1} } },
{ $sort : {anzahl : -1} },
{ $limit : 3 }
);
Was ist Map/Reduce?
•

Programmiermodel aus der funktionalen
Welt

•

Framework zur
– parallelen Verarbeitung
– von großen Datenmengen
– mittels verteilter Systeme

•

Populär geworden durch Google
– Wird zur Berechnung des Suchindex verwendet,

welcher Seiten zu Keywords zuordnet (Page Rank)
– http://research.google.com/archive/mapreduce.html
Map/Reduce mit MongoDB
MongoDB

map()

Daten

group(k)

emit(k,v)
Shard 1

• Iteriert über
alle
Dokumente

sort(k)

Shard 2

…
Shard n

reduce(k, values)
finalize(k, v)
k, v

k, v
•
•

Input = Output
Kann mehrfach laufen
Word Count: Problemstellung
INPUT
{
MongoDB
uses
MapReduce
}

{
There is a
map phase
}

{
There is a
reduce
phase
}

MAPPER

GROUP/SORT

REDUCER

OUTPUT

a: 2
is: 2
map: 1

Problem:
Wie häufig kommt
ein Wort in allen
Dokumenten vor?

mapreduce: 1
mongodb: 1
phase: 2

reduce: 1
there: 2
uses: 1
Word Count: Tweets
// Beispiel: Twitter-Datenbank mit Tweets
> db.tweets.findOne()
{
"_id" : ObjectId("4fb9fb91d066d657de8d6f38"),
"text" : "RT @RevRunWisdom: The bravest thing that men do is
love women #love",
"created_at" : "Thu Sep 02 18:11:24 +0000 2010",
…
"user" : {
"friends_count" : 0,
"profile_sidebar_fill_color" : "252429",
"screen_name" : "RevRunWisdom",
"name" : "Rev Run",
},
…
Word Count: Map Funktion
// Map Funktion mit Bereinigung der Daten
map = function() {
this.text.split(' ').forEach(function(word) {
// Entfernen von Whitespace
word = word.replace(/s/g, "");
// Entfernen alle Non-Word-Characters
word = word.replace(/W/gm,"");
// Finally emit the cleaned up word
if(word != "") {
emit(word, 1)
}
});
};
Word Count: Reduce Funktion
// Reduce Funktion
reduce = function(key, values) {
return values.length;
};
Word Count: Aufruf
// Anzeigen des Ergebnisses in der Konsole
> db.tweets.mapReduce(map, reduce, { out : { inline : 1 } } );
// Speichern des Ergebnisses in einer Collection
> db.tweets.mapReduce(map, reduce, { out : "tweets_word_count"} );
{
"result" : "tweets_word_count",
"timeMillis" : 19026,
"counts" : {
"input" : 53641,
"emit" : 559217,
"reduce" : 102057,
"output" : 131003
},
"ok" : 1,
}
Word Count: Ergebnis
// Ausgeben der 10 häufigsten Wörter in Tweets
> db.tweets_word_count.find().sort({"value" : -1}).limit(10)
{
{
{
{
{
{
{
{
{
{

"_id"
"_id"
"_id"
"_id"
"_id"
"_id"
"_id"
"_id"
"_id"
"_id"

:
:
:
:
:
:
:
:
:
:

"Miley", "value" : 31 }
"mil", "value" : 31 }
"andthenihitmydougie", "value" : 30 }
"programa", "value" : 30 }
"Live", "value" : 29 }
"Super", "value" : 29 }
"cabelo", "value" : 29 }
"listen", "value" : 29 }
"Call", "value" : 28 }
"DA", "value" : 28 }
Indexing
Indexe in MongoDB sind B-Trees
Abfragen, Einfügen und Löschen:
O(log(n))
Fehlende oder nicht
optimale Indexe sind
das häufigste
vermeidbare MongoDB
Performance-Problem
Wie lege ich Indexe an?
// Anlegen eines Index, wenn er noch nicht existiert
> db.recipes.createIndex({ main_ingredient: 1 })

// Der Client merkt sich den Index und wirft keinen Fehler
> db.recipes.ensureIndex({ main_ingredient: 1 })

* 1 für aufsteigend, -1 für absteigend
Was kann indexiert werden?
// Mehrere Felder (Compound Key Indexes)
> db.recipes.ensureIndex({
main_ingredient: 1,
calories: -1
})
// Arrays mit Werten (Multikey Indexes)
{
name: 'Chicken Noodle Soup’,
ingredients : ['chicken', 'noodles']
}
> db.recipes.ensureIndex({ ingredients: 1 })
Was kann indexiert werden?
// Subdokumente
{
name : 'Apple Pie',
contributor: {
name: 'Joe American',
id: 'joea123'
}
}
db.recipes.ensureIndex({ 'contributor.id': 1 })
db.recipes.ensureIndex({ 'contributor': 1 })
Wie verwalte ich Indexe?
// Auflisten aller Indexe einer Collection
> db.recipes.getIndexes()
> db.recipes.getIndexKeys()

// Löschen eines Index
> db.recipes.dropIndex({ ingredients: 1 })

// Löschen und Neuerzeugung aller Indexe
db.recipes.reIndex()

// Defaultindex auf _id
Weitere Optionen
•

Unique Indexe
– Nur eindeutige Werte erlaubt

•

Sparse Indexe
– Für Felder, die nicht in allen Dokumenten

vorkommen

•

Geospatial Indexe
– Zur Modellierung von Geoinformationen

•

TTL Collections
– Verfallen nach x Sekunden
Unique Indexe
// Der Name eines Rezepts muss eindeutig sein
> db.recipes.ensureIndex( { name: 1 }, { unique: true } )

// Erzwingen eines Index auf einer Collection mit nicht eindeutigen
// Namen – Die Duplikate werden gelöscht
> db.recipes.ensureIndex(
{ name: 1 },
{ unique: true, dropDups: true }
)

* dropDups bitte mit sehr viel Vorsicht anwenden!
Sparse Indexe
// Nur Dokumente mit dem Feld calories werden indexiert
> db.recipes.ensureIndex(
{ calories: -1 },
{ sparse: true }
)
// Kombination mit einem Unique Index möglich
> db.recipes.ensureIndex(
{ name: 1 , calories: -1 },
{ unique: true, sparse: true }
)
* Fehlende Felder werden im Index als null gespeichert
Geospatial Indexe
// Hinzufügen von Längen- und Breitengraden
{
name: ‚codecentric Frankfurt’,
loc: [ 50.11678, 8.67206]
}
// Indexierung der Koordinaten
> db.locations.ensureIndex( { loc : '2d' } )

// Abfrage nach Orten in der Nähe von codecentric Frankfurt
> db.locations.find({
loc: { $near: [ 50.1, 8.7 ] }
})
TTL Collections
// Die Dokumente müssen ein Datum des Typs BSON UTC haben
{ ' submitted_date ' : ISODate('2012-10-12T05:24:07.211Z'), … }

// Dokumente werden automatisch nach 'expireAfterSeconds'
// Sekunden gelöscht
> db.recipes.ensureIndex(
{ submitted_date: 1 },
{ expireAfterSeconds: 3600 }
)
Limitierungen von Indexen
•

Collections können nicht mehr als 64 Indexe haben.

•

Indexschlüssel können nicht größer als 1024 Byte
sein.

•

Der Name eines Index inklusive Namespace muss
kleiner als 128 Zeichen sein.

•

Abfragen können nur einen Index verwenden
– Ausnahme: Abfragen mit $or

•

Indexe verbrauchen Speichern und verlangsamen
das Schreiben von Daten
Optimierung von Indexen
Vorgehensweise
1. Langsame Abfragen identifizieren
2. Mittels explain() mehr über die

langsame Abfrage herausfinden
3. Anlegen der Indexe auf den

abgefragten Feldern
4. Optimierung der Abfragen anhand

der verwendeten Indexe
1. Langsame Abfragen
identifizieren
> db.setProfilingLevel( n , slowms=100ms )

n=0: Profiler abgeschaltet
n=1: Protokollieren aller Abfragen langsamer als slowms
n=2: Protokollieren aller Operationen

> db.system.profile.find()

* Die Collection profile ist eine Capped Collection und hat daher eine feste
Anzahl von Einträgen
2. Benutzung von explain()
> db.recipes.find( { calories:
{ $lt : 40 } }
).explain( )
{
"cursor" : "BasicCursor" ,
"n" : 42,
"nscannedObjects” : 53641
"nscanned" : 53641,
...
"millis" : 252,
...
}
* Keine Verwendung von Plänen aus dem Cache und erneuten Ausführungen
2. Metriken des Executionplans I
• Cursor
– Der Typ des Cursors. BasicCursor bedeutet, dass

kein Index benutzt wurde

• n
– Die Anzahl der passenden Dokumente

• nscannedObjects
– Die Anzahl der gescannten Dokumente

• nscanned
– Die Anzahl der untersuchten Einträge

(Indexeinträge oder Dokumente)
2. Metriken des Executionplans II
• millis
– Ausführungszeit der Abfrage

• Komplette Referenz unter
– http://docs.mongodb.org/manual/reference/explain

Das Verhältnis der gescannten
zu den gefundenen
Dokumenten sollte möglichst
nahe an 1 sein!
3. Anlegen der Indexe auf den
abgefragten Feldern
4. Optimierung der Abfragen
anhand der verwendeten Indexe
// Bei folgendem Index…
> db.collection.ensureIndex({ a:1, b:1 , c:1, d:1 })
//
//
>
>

… können die folgenden Sortieroperationen und Abfragen den
Index benutzen
db.collection.find( ).sort({ a:1 })
db.collection.find( ).sort({ a:1, b:1 })

> db.collection.find({ a:4 }).sort({ a:1, b:1 })
> db.collection.find({ b:5 }).sort({ a:1, b:1 })
4. Optimierung der Abfragen
anhand der verwendeten Indexe
// Bei folgendem Index…
> db.collection.ensureIndex({ a:1, b:1, c:1, d:1 })

// … können diese Abfragen ihn nicht verwenden
> db.collection.find( ).sort({ b: 1 })
> db.collection.find({ b: 5 }).sort({ b: 1 })
4. Optimierung der Abfragen
anhand der verwendeten Indexe
// Bei folgendem Index…
> db.recipes.ensureIndex({ main_ingredient: 1, name: 1 })
// … verwendet diese Abfrage nur Felder des Index
> db.recipes.find(
{ main_ingredient: 'chicken’ },
{ _id: 0, name: 1 }
)
// Das Feld indexOnly bei explain() zeigt dies an
> db.recipes.find(
{ main_ingredient: 'chicken' },
{ _id: 0, name: 1 }
).explain()
{
"indexOnly": true,
}
Index manuell angeben
// MongoDB mitteilen, welcher Index verwendet werden soll
> db.recipes.find({
calories: { $lt: 1000 } }
).hint({ _id: 1 })

// Die Verwendung von Indexen ausschalten (z.B. zur Performance// messung
> db.recipes.find(
{ calories: { $lt: 1000 } }
).hint({ $natural: 1 })
Häufige Stolperfallen
bei Indexen
Mehrere Index verwenden
// MongoDB kann nur einen Index pro Abfrage verwenden
> db.collection.ensureIndex({ a: 1 })
> db.collection.ensureIndex({ b: 1 })

// Nur einer der beiden obigen Indexe wird verwendet
> db.collection.find({ a: 3, b: 4 })
Zusammengesetzte Indexe
// Zusammengesetzte Indexe sind im Allgemeinen sehr effektiv
> db.collection.ensureIndex({ a: 1, b: 1, c: 1 })

// Aber nur wenn die Abfrage ein Präfix des Indexes ist…

// Diese Abfrage kann den Index nicht effektiv verwenden
db.collection.find({ c: 2 })

// …diese Abfrage hingegen schon
db.collection.find({ a: 3, b: 5 })
Indexe mit geringer
Selektivität
// Folgendes Feld hat nur sehr wenige eindeutige Werte
> db.collection.distinct('status’)
[ 'new', 'processed' ]
// Ein Index auf diesem Feld bringt nur sehr wenig
> db.collection.ensureIndex({ status: 1 })
> db.collection.find({ status: 'new' })
// Besser ist ein zusammengesetzter Index zusammen mit einem
// anderen Feld
> db.collection.ensureIndex({ status: 1, created_at: -1 })
> db.collection.find(
{ status: 'new' }
).sort({ created_at: -1 })
Reguläre Ausdrücke & Indexe
> db.users.ensureIndex({ username: 1 })

// Abfragen mit regulären Ausdrücken, die linksgebunden sind
// können den Index verwenden
> db.users.find({ username: /^joe smith/ })

// Generische Abfragen mit regulären Ausdrücken hingegen nicht…
> db.users.find({username: /smith/ })

// Ebenso nicht schreibungsunabhängige Abfragen…
> db.users.find({ username: /Joe/i })
Negation
// Bei Negationen können Indexe nicht verwendet werden
> db.things.ensureIndex({ x: 1 })
// z.B. bei Abfragen mit not equal
> db.things.find({ x: { $ne: 3 } })
// …oder Abfragen mit not in
> db.things.find({ x: { $nin: [2, 3, 4 ] } })
// …oder Abfragen mit dem $not Operator
> db.people.find({ name: { $not: 'John Doe' } })
Konsistenz beim Schreiben
und Lesen von Daten
Starke Konsistenz
Verzögerte Konsistenz
Write Concern - Schreibmodi
•

Bestätigung durch das Netzwerk

•

Bestätigung durch MongoDB

•

Bestätigung durch das Journal

•

Bestätigung durch Secondaries

•

Bestätigung durch Tagging
Bestätigung durch das Netzwerk
„Fire and forget“
Bestätigung durch MongoDB
Wait for Error
Bestätigung durch das Journal
Wait for Journal Sync
Bestätigung durch Secondaries
Wait for Replication
Tagging beim Schreiben
•

Verfügbar seit Version 2.0

•

Ermöglicht stärkere Kontrolle woher Daten
gelesen und wohin geschrieben werden

•

Jeder Knoten kann mehrere Tags haben
– tags: {dc: "ny"}
– tags: {dc: "ny", subnet: „192.168", rack: „row3rk7"}

•

Erlaubt das Anlegen für Regeln für das Write
Concern pro Replikaset

•

Anpassung der Regeln ohne Codeänderung
Beispiel für Tagging
{
_id : "mySet",
members : [
{_id : 0, host : "A", tags : {"dc": "ny"}},
{_id : 1, host : "B", tags : {"dc": "ny"}},
{_id : 2, host : "C", tags : {"dc": "sf"}},
{_id : 3, host : "D", tags : {"dc": "sf"}},
{_id : 4, host : "E", tags : {"dc": "cloud"}}],
settings : {
getLastErrorModes : {
allDCs : {"dc" : 3},
someDCs : {"dc" : 2}} }
}
> db.blogs.insert({...})
> db.runCommand({getLastError : 1, w : "someDCs"})
Bestätigung durch alle Datenzentren

Wait for Replication (Tagging)
Setzen des Write Concerns
// Wait for network acknowledgement
> db.runCommand( { getLastError: 1, w: 0 } )
// Wait for error (Default)
> db.runCommand( { getLastError: 1, w: 1 } )
// Wait for journal sync
> db.runCommand( { getLastError: 1, w: 1, j: "true" } )
// Wait for replication
> db.runCommand( { getLastError: 1, w: “majority" } ) // Mehrheit
> db.runCommand( { getLastError: 1, w: 3 } ) // # der Secondaries
Modi zum Lesen von Daten
(Seit Version 2.2)
•

Nur Primary

(primary)

•

Primary bevorzugt

(primaryPreferred)

•

Nur Secondaries

(secondary)

•

Secondaries bevorzugt

(secondaryPreferred)

•

Nähester Knoten

(Nearest)

Falls mehr als ein Knoten möglich ist, wird immer der
näheste Knoten zum Lesen der Daten verwendet. (Alle
Modi außer Primary)
Read

Nur Primary
primary
Read
Read

Primary bevorzugt
primaryPreferred
Read

Read

Nur Secondaries
secondary
Read

Read
Read

Secondaries bevorzugt
secondaryPreferred
Read

Read
Read

Nähester Knoten
nearest
Tagging beim Lesen
•

Ermöglicht eine individuelle Kontrolle
woher Daten gelesen werden
– z.B. { "disk": "ssd", "use": "reporting" }

•

Lässt sich mit den Standard-Lese-Modi
kombinieren
– Außer dem Modus „Nur Primary“
Setzen der Read Preference
// Nur Primary
> cursor.setReadPref( “primary" )
// Primary bevorzugt
> cursor.setReadPref( “primaryPreferred" )
….
// Nur Secondaries mit Tagging
> cursor.setReadPref( “secondary“, [ rack : 2 ] )

Aufruf der Methode auf dem Cursor muss
vor dem Lesen der Dokumente erfolgen
Java API & Frameworks
Übersicht
Jongo

Spring Data
MongoDB

Morphia

Hibernate
OGM

JPA

JDBC

MongoDB Java Driver
MongoDB
MongoDB Java Treiber
MongoDB Treiber
•

Ein Wire Protokoll für alle
Programmiersprachen

•

Eine Implementierung des Treibers pro
Sprache

•

Hauptaufgaben:
– Konvertierung der sprachspezifischen

Datenstrukturen nach BSON
– Generierung der ObjectId für das Feld _id
MongoDB Java Treiber
•

Ein JAR ohne weitere Abhängigkeiten:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.11.3</version>
</dependency>

Verfügbar auf Github:
https://github.com/mongodb/mongo-java-driver
Verbindungsaufbau
import com.mongodb.MongoClient;
// Default: localhost:27017
mongo = new MongoClient();
// Replica set
mongo = new MongoClient(Arrays.asList(
new ServerAddress("replicant01", 10001),
new ServerAddress("replicant02", 10002),
new ServerAddress("replicant03", 10003)
));
// Sharding: mongos server
mongo = new MongoClient("mongos01", 4711);
Zugriff auf Datenbank und
Collection
import com.mongodb.DB;
import com.mongodb.DBCollection;
DB db = mongo.getDB("test");
DBCollection collection =
db.getCollection("foo");
Dokument einfügen
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
// insert document
DBObject doc = new BasicDBObject();
doc.put("date", new Date());
doc.put("i", 42);
collection.insert(doc);
Dokumente abfragen
import com.mongodb.DBCursor;
DBCursor cursor;
cursor = collection.find(); // all documents
// documents w/ {i: 42}
cursor = collection.find(
new BasicDBObject("i", 42) );
document = cursor.next();
...
Beispiel: Bestellung

> db.order.find( {"items.quantity": ? } )
Beispiel: Bestellung I
DB db = mongo.getDB("test");
DBCollection collection = db.getCollection("order");
DBObject order;
List<DBObject> items = new ArrayList<DBObject>();
DBObject item;
// order
order = new BasicDBObject();
order.put("date", new Date());
order.put("custInfo" , „Sheldon Cooper");
// items
item = new BasicDBObject();
item.put("quantity", 1);
item.put("price", 47.11);
item.put("desc", "Item #1");
items.add(item);
item = new BasicDBObject();
item.put("quantity", 2);
item.put("price", 42.0);
item.put("desc", "Item #2");
items.add(item);
order.put("items", items);
collection.insert(order);
Beispiel: Bestellung II
DB db = mongo.getDB("test");
DBCollection collection = db.getCollection("order");
DBObject query;
DBObject document;
DBCursor cursor;
query = new BasicDBObject("items.quantity", 2);
cursor = collection.find(query);
while ( cursor.hasNext() ) {
document = cursor.next();
println(document);
}
Jongo
Kurzüberblick über Jongo
Entwickler
Lizenz
Dokumentation
Hauptmerkmale

Benoît Guérout, Yves Amsellem
Apache License, Version 2.0
http://jongo.org/
• Object/Document Mapping
• Eigene Query API
Query in Java as in Mongo Shell
Jongo: Object Mapping
public class Order {
private ObjectId id;
private Date date;
@JsonProperty("custInfo") private String customerInfo;
List<Item> items;
…
}
public class Item {
private int quantity;
private double price;
@JsonProperty("desc") private String description;
…
}
Jongo: Abfragen
// Java driver API
MongoClient mc = new MongoClient();
DB db = mc.getDB("odm_jongo");
// Jongo API entry point
Jongo jongo = new Jongo(db);
MongoCollection orders = jongo.getCollection("order");
// no DAO needed
Iterable<Order> result =
orders.find("{"items.quantity": #}", 2).as(Order.class);
// supports projection
Iterable<X> result =
orders.find().fields("{_id:0, date:1,
custInfo:1}").as(X.class);
Morphia
Kurzüberblick über Morphia

Entwickler
Lizenz
Dokumentation

Scott Hernandez, James Green
Apache License, Version 2.0
https://github.com/jmkgreen/morph
ia/wiki/Overview
Hauptmerkmale • Object/Document Mapping
• Eigene Query API
• Unterstützung für DAO‘s
Morphia: Object Mapping
public class Order {
@Id private ObjectId id;
private Date date;
@Property("custInfo") private String customerInfo;
@Embedded List<Item> items;
...
}
public class Item {
private int quantity;
private double price;
@Property("desc") private String description;
...
}
Morphia: Abfragen
public class OrderDao extends BasicDAO<Order, ObjectId> {
List<Order> findByItemsQuantity(int quantity) {
return
find( createQuery().filter("items.quantity", quantity))
.asList();
}
List<Order> findByItemsPriceGreaterThan(double price) {
return
find(
createQuery().field("items.price").greaterThan(price) )
.asList();
}
…
}
Morphia: Eigene Syntax für
Abfragen
Morphia

Mongo Query

=
!=, <>
>, <, >=,<=
in, nin
elem
…

$eq
$neq
$gt, $lt, $gte, $lte
$in, $nin
$elemMatch
….
Spring Data MongoDB
Kurzüberblick über
Spring Data MongoDB
Hersteller
Lizenz
Dokumentation

VMware / SpringSource
Apache License, Version 2.0
http://www.springsource.org/spring
-data/mongodb
Hauptmerkmale • Repository Support
• Object/Document Mapping
• Templating
Spring Data
CrudRepository
Spring Data
JPA

PagingAndSortingRepository
Spring Data
Neo4j

MongoReposito
ry

GraphRepos itory

MongoT em plate

JpaRepository

Spring Data
MongoDB

Neo4jTemplate
Em bedded

JPA
JDBC
RDBMS

Spring Data
…

RES T

Mongo Java
Driver
Mongo
DB

Neo4j

…

Einheitliche Architektur für relationale
Datenbanken sowie für unterstützte NoSQL-Stores
Spring Data MongoDB
•

Repository Support
– Abfragen werden aus den Methodensignaturen erstellt
– Annotationen für Abfragen

•

Object-Document-Mapping
– Annotationen: @Document, @Field, @Index, …
– Klassen werden auf Collections gemappt, Javaobjekte auf

Dokumente

•

Templating
–
–
–
–

Abstraktion der Ressourcen
Konfigurierbarkeit der Verbindungen zu MongoDB
Abdeckung des Lebenszyklus einer Collection
Unterstützung für Map/Reduce & Aggregation Framework
Spring Data MongoDB:
Konfiguration
<!-- Connection to MongoDB server -->
<mongo:db-factory host="localhost" port="27017" dbname="test" />
<!-- MongoDB Template -->
<bean id="mongoTemplate,
class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
<!-- Package w/ automagic repositories -->
<mongo:repositories base-package="mongodb" />
Spring Data MongoDB:
Template
<mongo:mongo host="${mongo.host}" port="${mongo.port}">
<mongo:options
connections-per-host="${mongo.connectionsPerHost}„
threads-allowed-to-block-for-connection
multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}„
connect-timeout="${mongo.connectTimeout}„
max-wait-time="${mongo.maxWaitTime}„
auto-connect-retry="${mongo.autoConnectRetry}„
socket-keep-alive="${mongo.socketKeepAlive}„
socket-timeout="${mongo.socketTimeout}„
slave-ok="${mongo.slaveOk}„
write-number="1„
write-timeout="0„
write-fsync="true"/>
</mongo:mongo>
<mongo:db-factory dbname= "test" mongo-ref="mongo"/>
Spring Data MongoDB:
Object Mapping
public class Order {
@Id private String id;
private Date date;
@Field("custInfo") private String customerInfo;
List<Item> items; ...
}
public class Item {
private int quantity;
private double price;
@Field("desc") private String description;
...
}
Spring Data MongoDB:
Repository Support
public interface OrderRepository extends
MongoRepository<Order, String> {
List<Order> findByItemsQuantity(int
quantity);
List<Order>
findByItemsPriceGreaterThan(double
price);
}
Spring Data MongoDB:
Zusätzliche Unterstützung für…
•

Map/Reduce & das Aggregation Framework

•

Das Management von Indexen

•

Große Dateien mittels GridFS

•

Geoinformatische Indexe und Abfragen

•

Optimistisches Locking
Hibernate OGM
Kurzüberblick über
Hibernate OGM MongoDB
Hersteller
Lizenz
Dokumentation

JBoss / Redhat
GNU LGPL, Version 2.1
http://www.hibernate.org/subproject
s/ogm.html
Hauptmerkmale • JPA API (Teilweise)
• JPQL Query Language
Hibernate OGM
• Implementiert ein Subset der JPA API
• JP-QL Anfragen werden in native

Datenbankabfragen übersetzt
• Unterstützt Infinispan, EhCache,

MongoDB
Architektur von
Hibernate OGM

Source:
http://docs.jboss.org/hibernate/ogm/4.0/reference/en-US/html/ogm-architecture.html#d0e409
Hibernate OGM MongoDB:
Konfiguration
<persistence version="2.0" …>
<persistence-unit name="primary">
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>hibernate.Order</class>
<class>hibernate.Item</class>
<properties>
<property name="hibernate.ogm.datastore.provider"
value="org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastorePr
ovider"/>
<property name="hibernate.ogm.mongodb.database" value=„odm"/>
<property name="hibernate.ogm.mongodb.host" value=„localhost"/>
<property name="hibernate.ogm.mongodb.port" value=„27017"/>
</properties>
</persistence-unit>
</persistence>
Hibernate OGM MongoDB:
Object Mapping
@Entity
@NamedQuery(
name="byItemsQuantity",
query = "SELECT o FROM Order o JOIN o.items i WHERE i.quantity = :quantity"
)
public class Order {
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Id private String id;
private Date date;
@Column(name = "custInfo") private String customerInfo;
@ElementCollection
private List<Item> items;
@Embeddable
public class Item {
private int quantity;
private double price;
@Column(name="desc") private String description;
...
Hibernate OGM MongoDB:
Aktueller Status
•

Frühes Beta-Stadium

• Aktuell nur Speichern / Mergen /

Löschen von Daten möglich
• Noch keine Unterstützung für

Abfragen
• Benutzt eine relationale API
Not yet ready for prime time…
Empfehlung
Was sollte ich einsetzen?
- „Ready for production“

JPA

Hibernate
OGM

Spring Data
MongoDB

- Frühes Betastadium
- Diskrepanz in API

- Aktive Community

- Ältestes Framework
- Nicht so mächtig wie Spring

Morphia
Der „bessere“ Treiber

Jongo
JDBC

MongoDB Java Driver
- „Ready for production“
- Von MongoDB Inc. unterstützt
MongoDB
Getting started…

One more thing…
MongoDB User Group

https://www.xing.com/net/mongodb-ffm/
http://www.meetup.com/Frankfurt-Rhine-Main-MongoDB-User-Group/
MongoDB Munich 2013

http://www.mongodb.com/events/mongodb-munich-2013/
So Long, and Thanks for All the Fish!

Weitere ähnliche Inhalte

Was ist angesagt?

OOP 2013: Praktische Einführung in MongoDB
OOP 2013: Praktische Einführung in MongoDBOOP 2013: Praktische Einführung in MongoDB
OOP 2013: Praktische Einführung in MongoDB
Tobias Trelle
 
MongoDB Munich 2012: Spring Data MongoDB
MongoDB Munich 2012: Spring Data MongoDBMongoDB Munich 2012: Spring Data MongoDB
MongoDB Munich 2012: Spring Data MongoDB
Tobias Trelle
 
Back to Basics-Webinar 5: Einführung in das Aggregation-Framework
Back to Basics-Webinar 5: Einführung in das Aggregation-FrameworkBack to Basics-Webinar 5: Einführung in das Aggregation-Framework
Back to Basics-Webinar 5: Einführung in das Aggregation-Framework
MongoDB
 
2012-01-31 NoSQL in .NET
2012-01-31 NoSQL in .NET2012-01-31 NoSQL in .NET
2012-01-31 NoSQL in .NET
Johannes Hoppe
 
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDBBack to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
MongoDB
 
Einführung in Elasticsearch
Einführung in ElasticsearchEinführung in Elasticsearch
Einführung in Elasticsearch
Florian Hopf
 
Einführung CouchDB
Einführung CouchDBEinführung CouchDB
Einführung CouchDB
Oliver Kurowski
 
Fachmodell-First: Einstieg in das NoSQL-Schema-Design
Fachmodell-First: Einstieg in das NoSQL-Schema-DesignFachmodell-First: Einstieg in das NoSQL-Schema-Design
Fachmodell-First: Einstieg in das NoSQL-Schema-Design
Gregor Biswanger
 
MongoDB: Entwurfsmuster für das NoSQL-Schema-Design
MongoDB: Entwurfsmuster für das NoSQL-Schema-DesignMongoDB: Entwurfsmuster für das NoSQL-Schema-Design
MongoDB: Entwurfsmuster für das NoSQL-Schema-Design
Gregor Biswanger
 
Datenbankoptimierung
DatenbankoptimierungDatenbankoptimierung
Datenbankoptimierung
Cenarion Information Systems GmbH
 
Back to Basics - Webinar 6: Produktivsetzung einer Anwendung
Back to Basics - Webinar 6: Produktivsetzung einer AnwendungBack to Basics - Webinar 6: Produktivsetzung einer Anwendung
Back to Basics - Webinar 6: Produktivsetzung einer Anwendung
MongoDB
 
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
Carsten Hetzel
 
2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB
2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB
2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDBJohannes Hoppe
 
2012-05-14 NoSQL in .NET - mit Redis und MongoDB
2012-05-14 NoSQL in .NET - mit Redis und MongoDB2012-05-14 NoSQL in .NET - mit Redis und MongoDB
2012-05-14 NoSQL in .NET - mit Redis und MongoDB
Johannes Hoppe
 
C# Workshop - File Operations
C# Workshop - File OperationsC# Workshop - File Operations
C# Workshop - File Operations
Qiong Wu
 
Entity Framework hinter den Kulissen
Entity Framework hinter den KulissenEntity Framework hinter den Kulissen
Entity Framework hinter den Kulissen
André Krämer
 
Einfuehrung in mongo_db_iks
Einfuehrung in mongo_db_iksEinfuehrung in mongo_db_iks
Performance trotz Entity Framwork
Performance trotz Entity FramworkPerformance trotz Entity Framwork
Performance trotz Entity Framwork
André Krämer
 

Was ist angesagt? (20)

OOP 2013: Praktische Einführung in MongoDB
OOP 2013: Praktische Einführung in MongoDBOOP 2013: Praktische Einführung in MongoDB
OOP 2013: Praktische Einführung in MongoDB
 
MongoDB Munich 2012: Spring Data MongoDB
MongoDB Munich 2012: Spring Data MongoDBMongoDB Munich 2012: Spring Data MongoDB
MongoDB Munich 2012: Spring Data MongoDB
 
Back to Basics-Webinar 5: Einführung in das Aggregation-Framework
Back to Basics-Webinar 5: Einführung in das Aggregation-FrameworkBack to Basics-Webinar 5: Einführung in das Aggregation-Framework
Back to Basics-Webinar 5: Einführung in das Aggregation-Framework
 
2012-01-31 NoSQL in .NET
2012-01-31 NoSQL in .NET2012-01-31 NoSQL in .NET
2012-01-31 NoSQL in .NET
 
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDBBack to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
 
Einführung in Elasticsearch
Einführung in ElasticsearchEinführung in Elasticsearch
Einführung in Elasticsearch
 
Einführung CouchDB
Einführung CouchDBEinführung CouchDB
Einführung CouchDB
 
Fachmodell-First: Einstieg in das NoSQL-Schema-Design
Fachmodell-First: Einstieg in das NoSQL-Schema-DesignFachmodell-First: Einstieg in das NoSQL-Schema-Design
Fachmodell-First: Einstieg in das NoSQL-Schema-Design
 
MongoDB: Entwurfsmuster für das NoSQL-Schema-Design
MongoDB: Entwurfsmuster für das NoSQL-Schema-DesignMongoDB: Entwurfsmuster für das NoSQL-Schema-Design
MongoDB: Entwurfsmuster für das NoSQL-Schema-Design
 
Query Result Caching
Query Result CachingQuery Result Caching
Query Result Caching
 
Datenbankoptimierung
DatenbankoptimierungDatenbankoptimierung
Datenbankoptimierung
 
Back to Basics - Webinar 6: Produktivsetzung einer Anwendung
Back to Basics - Webinar 6: Produktivsetzung einer AnwendungBack to Basics - Webinar 6: Produktivsetzung einer Anwendung
Back to Basics - Webinar 6: Produktivsetzung einer Anwendung
 
Fly2pdf
Fly2pdfFly2pdf
Fly2pdf
 
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
 
2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB
2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB
2012-05-10 - UG Karlsruhe: NoSQL in .NET - mit Redis und MongoDB
 
2012-05-14 NoSQL in .NET - mit Redis und MongoDB
2012-05-14 NoSQL in .NET - mit Redis und MongoDB2012-05-14 NoSQL in .NET - mit Redis und MongoDB
2012-05-14 NoSQL in .NET - mit Redis und MongoDB
 
C# Workshop - File Operations
C# Workshop - File OperationsC# Workshop - File Operations
C# Workshop - File Operations
 
Entity Framework hinter den Kulissen
Entity Framework hinter den KulissenEntity Framework hinter den Kulissen
Entity Framework hinter den Kulissen
 
Einfuehrung in mongo_db_iks
Einfuehrung in mongo_db_iksEinfuehrung in mongo_db_iks
Einfuehrung in mongo_db_iks
 
Performance trotz Entity Framwork
Performance trotz Entity FramworkPerformance trotz Entity Framwork
Performance trotz Entity Framwork
 

Andere mochten auch

MongoDB Roadmap
MongoDB RoadmapMongoDB Roadmap
MongoDB Roadmap
MongoDB
 
Webinar: What's New in MongoDB 3.2
Webinar: What's New in MongoDB 3.2Webinar: What's New in MongoDB 3.2
Webinar: What's New in MongoDB 3.2
MongoDB
 
Joins and Other Aggregation Enhancements Coming in MongoDB 3.2
Joins and Other Aggregation Enhancements Coming in MongoDB 3.2Joins and Other Aggregation Enhancements Coming in MongoDB 3.2
Joins and Other Aggregation Enhancements Coming in MongoDB 3.2
MongoDB
 
Content Management with MongoDB by Mark Helmstetter
 Content Management with MongoDB by Mark Helmstetter Content Management with MongoDB by Mark Helmstetter
Content Management with MongoDB by Mark Helmstetter
MongoDB
 
BI mit Apache Hadoop (CDH)
BI mit Apache Hadoop (CDH)BI mit Apache Hadoop (CDH)
BI mit Apache Hadoop (CDH)Alexander Alten
 
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Nils Adermann
 
Why NoSQL and MongoDB for Big Data
Why NoSQL and MongoDB for Big DataWhy NoSQL and MongoDB for Big Data
Why NoSQL and MongoDB for Big Data
William LaForest
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012
Steven Francia
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam HelmanMongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam Helman
Hakka Labs
 
An Introduction to Big Data, NoSQL and MongoDB
An Introduction to Big Data, NoSQL and MongoDBAn Introduction to Big Data, NoSQL and MongoDB
An Introduction to Big Data, NoSQL and MongoDB
William LaForest
 
MongoDB Pros and Cons
MongoDB Pros and ConsMongoDB Pros and Cons
MongoDB Pros and Cons
johnrjenson
 
Strengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDBStrengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDB
lehresman
 
Data Streaming with Apache Kafka & MongoDB - EMEA
Data Streaming with Apache Kafka & MongoDB - EMEAData Streaming with Apache Kafka & MongoDB - EMEA
Data Streaming with Apache Kafka & MongoDB - EMEA
Andrew Morgan
 
PyData: The Next Generation
PyData: The Next GenerationPyData: The Next Generation
PyData: The Next Generation
Wes McKinney
 
MongoDB 3.4 webinar
MongoDB 3.4 webinarMongoDB 3.4 webinar
MongoDB 3.4 webinar
Andrew Morgan
 
MongoDB and hadoop
MongoDB and hadoopMongoDB and hadoop
MongoDB and hadoop
Steven Francia
 
MongoDB for Beginners
MongoDB for BeginnersMongoDB for Beginners
MongoDB for Beginners
Enoch Joshua
 
Mongo db
Mongo dbMongo db
Mongo db
Akshay Mathur
 
SQL, NoSQL, BigData in Data Architecture
SQL, NoSQL, BigData in Data ArchitectureSQL, NoSQL, BigData in Data Architecture
SQL, NoSQL, BigData in Data Architecture
Venu Anuganti
 
Cloudera Customer Success Story
Cloudera Customer Success StoryCloudera Customer Success Story
Cloudera Customer Success Story
Xpand IT
 

Andere mochten auch (20)

MongoDB Roadmap
MongoDB RoadmapMongoDB Roadmap
MongoDB Roadmap
 
Webinar: What's New in MongoDB 3.2
Webinar: What's New in MongoDB 3.2Webinar: What's New in MongoDB 3.2
Webinar: What's New in MongoDB 3.2
 
Joins and Other Aggregation Enhancements Coming in MongoDB 3.2
Joins and Other Aggregation Enhancements Coming in MongoDB 3.2Joins and Other Aggregation Enhancements Coming in MongoDB 3.2
Joins and Other Aggregation Enhancements Coming in MongoDB 3.2
 
Content Management with MongoDB by Mark Helmstetter
 Content Management with MongoDB by Mark Helmstetter Content Management with MongoDB by Mark Helmstetter
Content Management with MongoDB by Mark Helmstetter
 
BI mit Apache Hadoop (CDH)
BI mit Apache Hadoop (CDH)BI mit Apache Hadoop (CDH)
BI mit Apache Hadoop (CDH)
 
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
 
Why NoSQL and MongoDB for Big Data
Why NoSQL and MongoDB for Big DataWhy NoSQL and MongoDB for Big Data
Why NoSQL and MongoDB for Big Data
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam HelmanMongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam Helman
 
An Introduction to Big Data, NoSQL and MongoDB
An Introduction to Big Data, NoSQL and MongoDBAn Introduction to Big Data, NoSQL and MongoDB
An Introduction to Big Data, NoSQL and MongoDB
 
MongoDB Pros and Cons
MongoDB Pros and ConsMongoDB Pros and Cons
MongoDB Pros and Cons
 
Strengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDBStrengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDB
 
Data Streaming with Apache Kafka & MongoDB - EMEA
Data Streaming with Apache Kafka & MongoDB - EMEAData Streaming with Apache Kafka & MongoDB - EMEA
Data Streaming with Apache Kafka & MongoDB - EMEA
 
PyData: The Next Generation
PyData: The Next GenerationPyData: The Next Generation
PyData: The Next Generation
 
MongoDB 3.4 webinar
MongoDB 3.4 webinarMongoDB 3.4 webinar
MongoDB 3.4 webinar
 
MongoDB and hadoop
MongoDB and hadoopMongoDB and hadoop
MongoDB and hadoop
 
MongoDB for Beginners
MongoDB for BeginnersMongoDB for Beginners
MongoDB for Beginners
 
Mongo db
Mongo dbMongo db
Mongo db
 
SQL, NoSQL, BigData in Data Architecture
SQL, NoSQL, BigData in Data ArchitectureSQL, NoSQL, BigData in Data Architecture
SQL, NoSQL, BigData in Data Architecture
 
Cloudera Customer Success Story
Cloudera Customer Success StoryCloudera Customer Success Story
Cloudera Customer Success Story
 

Ähnlich wie MongoDB für Java-Programmierer

JSF und JPA effizient kombinieren (W-JAX 2011)
JSF und JPA effizient kombinieren (W-JAX 2011)JSF und JPA effizient kombinieren (W-JAX 2011)
JSF und JPA effizient kombinieren (W-JAX 2011)
Michael Kurz
 
Einführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenEinführung in NoSQL-Datenbanken
Einführung in NoSQL-Datenbanken
Tobias Trelle
 
mongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - GrundlagenmongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - Grundlagen
inovex GmbH
 
Einfuehrung in Elasticsearch
Einfuehrung in ElasticsearchEinfuehrung in Elasticsearch
Einfuehrung in Elasticsearch
Florian Hopf
 
Domain Driven Design in Rails
Domain Driven Design in RailsDomain Driven Design in Rails
Domain Driven Design in Rails
Angelo Maron
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
GFU Cyrus AG
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Daniel Havlik
 
Yes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-EntwicklerYes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-Entwickler
Gregor Biswanger
 
Dokumentation schreiben kann spass machen
Dokumentation schreiben kann spass machenDokumentation schreiben kann spass machen
Dokumentation schreiben kann spass machen
Sebastian Hempel
 
Node.js
Node.jsNode.js
Elasticsearch & docker mit logstash, jdbc und ruby
Elasticsearch & docker mit logstash, jdbc und rubyElasticsearch & docker mit logstash, jdbc und ruby
Elasticsearch & docker mit logstash, jdbc und ruby
SchanzDieter
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
Jens Siebert
 
HashiTalks: DACH - Die Verwendung von IaC im DevOps Prozess
HashiTalks: DACH - Die Verwendung von IaC im DevOps ProzessHashiTalks: DACH - Die Verwendung von IaC im DevOps Prozess
HashiTalks: DACH - Die Verwendung von IaC im DevOps Prozess
Jochen Zehnder
 
Datenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiDatenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiChristian Baranowski
 
DB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBaseDB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBase
gedoplan
 
Docker-Images mit vorinstallierter Instanz einer Oracle-DB
Docker-Images mit vorinstallierter Instanz einer Oracle-DBDocker-Images mit vorinstallierter Instanz einer Oracle-DB
Docker-Images mit vorinstallierter Instanz einer Oracle-DB
Peter Ramm
 
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDISchlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
adesso AG
 
Oracle vs. PostgreSQL - Unterschiede in 45 Minuten
Oracle vs. PostgreSQL - Unterschiede in 45 MinutenOracle vs. PostgreSQL - Unterschiede in 45 Minuten
Oracle vs. PostgreSQL - Unterschiede in 45 Minuten
Markus Flechtner
 
Heterogene Daten(-strukturen) in der Oracle Datenbank
Heterogene Daten(-strukturen) in der Oracle DatenbankHeterogene Daten(-strukturen) in der Oracle Datenbank
Heterogene Daten(-strukturen) in der Oracle Datenbank
Ulrike Schwinn
 
Backbase Intro
Backbase IntroBackbase Intro
Backbase Intro
Béla Varga
 

Ähnlich wie MongoDB für Java-Programmierer (20)

JSF und JPA effizient kombinieren (W-JAX 2011)
JSF und JPA effizient kombinieren (W-JAX 2011)JSF und JPA effizient kombinieren (W-JAX 2011)
JSF und JPA effizient kombinieren (W-JAX 2011)
 
Einführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenEinführung in NoSQL-Datenbanken
Einführung in NoSQL-Datenbanken
 
mongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - GrundlagenmongoDB im Einsatz - Grundlagen
mongoDB im Einsatz - Grundlagen
 
Einfuehrung in Elasticsearch
Einfuehrung in ElasticsearchEinfuehrung in Elasticsearch
Einfuehrung in Elasticsearch
 
Domain Driven Design in Rails
Domain Driven Design in RailsDomain Driven Design in Rails
Domain Driven Design in Rails
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012
 
Yes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-EntwicklerYes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-Entwickler
 
Dokumentation schreiben kann spass machen
Dokumentation schreiben kann spass machenDokumentation schreiben kann spass machen
Dokumentation schreiben kann spass machen
 
Node.js
Node.jsNode.js
Node.js
 
Elasticsearch & docker mit logstash, jdbc und ruby
Elasticsearch & docker mit logstash, jdbc und rubyElasticsearch & docker mit logstash, jdbc und ruby
Elasticsearch & docker mit logstash, jdbc und ruby
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
HashiTalks: DACH - Die Verwendung von IaC im DevOps Prozess
HashiTalks: DACH - Die Verwendung von IaC im DevOps ProzessHashiTalks: DACH - Die Verwendung von IaC im DevOps Prozess
HashiTalks: DACH - Die Verwendung von IaC im DevOps Prozess
 
Datenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiDatenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence Api
 
DB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBaseDB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBase
 
Docker-Images mit vorinstallierter Instanz einer Oracle-DB
Docker-Images mit vorinstallierter Instanz einer Oracle-DBDocker-Images mit vorinstallierter Instanz einer Oracle-DB
Docker-Images mit vorinstallierter Instanz einer Oracle-DB
 
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDISchlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
 
Oracle vs. PostgreSQL - Unterschiede in 45 Minuten
Oracle vs. PostgreSQL - Unterschiede in 45 MinutenOracle vs. PostgreSQL - Unterschiede in 45 Minuten
Oracle vs. PostgreSQL - Unterschiede in 45 Minuten
 
Heterogene Daten(-strukturen) in der Oracle Datenbank
Heterogene Daten(-strukturen) in der Oracle DatenbankHeterogene Daten(-strukturen) in der Oracle Datenbank
Heterogene Daten(-strukturen) in der Oracle Datenbank
 
Backbase Intro
Backbase IntroBackbase Intro
Backbase Intro
 

Mehr von Uwe Printz

Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?
Uwe Printz
 
Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?
Uwe Printz
 
Hadoop meets Agile! - An Agile Big Data Model
Hadoop meets Agile! - An Agile Big Data ModelHadoop meets Agile! - An Agile Big Data Model
Hadoop meets Agile! - An Agile Big Data Model
Uwe Printz
 
Hadoop & Security - Past, Present, Future
Hadoop & Security - Past, Present, FutureHadoop & Security - Past, Present, Future
Hadoop & Security - Past, Present, Future
Uwe Printz
 
Hadoop Operations - Best practices from the field
Hadoop Operations - Best practices from the fieldHadoop Operations - Best practices from the field
Hadoop Operations - Best practices from the field
Uwe Printz
 
Apache Spark
Apache SparkApache Spark
Apache Spark
Uwe Printz
 
Lightning Talk: Agility & Databases
Lightning Talk: Agility & DatabasesLightning Talk: Agility & Databases
Lightning Talk: Agility & Databases
Uwe Printz
 
Hadoop 2 - More than MapReduce
Hadoop 2 - More than MapReduceHadoop 2 - More than MapReduce
Hadoop 2 - More than MapReduce
Uwe Printz
 
Welcome to Hadoop2Land!
Welcome to Hadoop2Land!Welcome to Hadoop2Land!
Welcome to Hadoop2Land!
Uwe Printz
 
Hadoop 2 - Beyond MapReduce
Hadoop 2 - Beyond MapReduceHadoop 2 - Beyond MapReduce
Hadoop 2 - Beyond MapReduce
Uwe Printz
 
Hadoop 2 - Going beyond MapReduce
Hadoop 2 - Going beyond MapReduceHadoop 2 - Going beyond MapReduce
Hadoop 2 - Going beyond MapReduce
Uwe Printz
 
Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)
Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)
Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)
Uwe Printz
 
MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)
Uwe Printz
 
Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...
Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...
Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...
Uwe Printz
 
Introduction to Twitter Storm
Introduction to Twitter StormIntroduction to Twitter Storm
Introduction to Twitter Storm
Uwe Printz
 
Introduction to the Hadoop Ecosystem (FrOSCon Edition)
Introduction to the Hadoop Ecosystem (FrOSCon Edition)Introduction to the Hadoop Ecosystem (FrOSCon Edition)
Introduction to the Hadoop Ecosystem (FrOSCon Edition)
Uwe Printz
 
Introduction to the Hadoop Ecosystem (SEACON Edition)
Introduction to the Hadoop Ecosystem (SEACON Edition)Introduction to the Hadoop Ecosystem (SEACON Edition)
Introduction to the Hadoop Ecosystem (SEACON Edition)
Uwe Printz
 
Introduction to the Hadoop Ecosystem (codemotion Edition)
Introduction to the Hadoop Ecosystem (codemotion Edition)Introduction to the Hadoop Ecosystem (codemotion Edition)
Introduction to the Hadoop Ecosystem (codemotion Edition)
Uwe Printz
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
Uwe Printz
 
First meetup of the MongoDB User Group Frankfurt
First meetup of the MongoDB User Group FrankfurtFirst meetup of the MongoDB User Group Frankfurt
First meetup of the MongoDB User Group FrankfurtUwe Printz
 

Mehr von Uwe Printz (20)

Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?
 
Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?Hadoop 3.0 - Revolution or evolution?
Hadoop 3.0 - Revolution or evolution?
 
Hadoop meets Agile! - An Agile Big Data Model
Hadoop meets Agile! - An Agile Big Data ModelHadoop meets Agile! - An Agile Big Data Model
Hadoop meets Agile! - An Agile Big Data Model
 
Hadoop & Security - Past, Present, Future
Hadoop & Security - Past, Present, FutureHadoop & Security - Past, Present, Future
Hadoop & Security - Past, Present, Future
 
Hadoop Operations - Best practices from the field
Hadoop Operations - Best practices from the fieldHadoop Operations - Best practices from the field
Hadoop Operations - Best practices from the field
 
Apache Spark
Apache SparkApache Spark
Apache Spark
 
Lightning Talk: Agility & Databases
Lightning Talk: Agility & DatabasesLightning Talk: Agility & Databases
Lightning Talk: Agility & Databases
 
Hadoop 2 - More than MapReduce
Hadoop 2 - More than MapReduceHadoop 2 - More than MapReduce
Hadoop 2 - More than MapReduce
 
Welcome to Hadoop2Land!
Welcome to Hadoop2Land!Welcome to Hadoop2Land!
Welcome to Hadoop2Land!
 
Hadoop 2 - Beyond MapReduce
Hadoop 2 - Beyond MapReduceHadoop 2 - Beyond MapReduce
Hadoop 2 - Beyond MapReduce
 
Hadoop 2 - Going beyond MapReduce
Hadoop 2 - Going beyond MapReduceHadoop 2 - Going beyond MapReduce
Hadoop 2 - Going beyond MapReduce
 
Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)
Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)
Introduction to the Hadoop Ecosystem (IT-Stammtisch Darmstadt Edition)
 
MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)
 
Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...
Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...
Introduction to the Hadoop Ecosystem with Hadoop 2.0 aka YARN (Java Serbia Ed...
 
Introduction to Twitter Storm
Introduction to Twitter StormIntroduction to Twitter Storm
Introduction to Twitter Storm
 
Introduction to the Hadoop Ecosystem (FrOSCon Edition)
Introduction to the Hadoop Ecosystem (FrOSCon Edition)Introduction to the Hadoop Ecosystem (FrOSCon Edition)
Introduction to the Hadoop Ecosystem (FrOSCon Edition)
 
Introduction to the Hadoop Ecosystem (SEACON Edition)
Introduction to the Hadoop Ecosystem (SEACON Edition)Introduction to the Hadoop Ecosystem (SEACON Edition)
Introduction to the Hadoop Ecosystem (SEACON Edition)
 
Introduction to the Hadoop Ecosystem (codemotion Edition)
Introduction to the Hadoop Ecosystem (codemotion Edition)Introduction to the Hadoop Ecosystem (codemotion Edition)
Introduction to the Hadoop Ecosystem (codemotion Edition)
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
 
First meetup of the MongoDB User Group Frankfurt
First meetup of the MongoDB User Group FrankfurtFirst meetup of the MongoDB User Group Frankfurt
First meetup of the MongoDB User Group Frankfurt
 

MongoDB für Java-Programmierer

  • 2. About me Big Data Nerd Hadoop Trainer MongoDB Author Photography Enthusiast Travelpirate
  • 3. About us is a bunch of… Big Data Nerds Agile Ninjas Continuous Delivery Gurus Join us! Enterprise Java Specialists Performance Geeks
  • 4. Agenda • Buzzword Bingo • Überblick über MongoDB • Datenmanipulation • Indexing • Konsistenz beim Schreiben und Lesen von Daten • Java API & Frameworks
  • 7. Klassifizierung von NoSQL Key-Value Stores K V K V K V K 1 V K Column Stores V Graph Databases 1 1 1 1 1 1 1 1 1 1 Document Stores _id _id _id
  • 10. Die klassische Definition • The 3 V’s of Big Data Volume Velocity •Variety
  • 11. «Big Data» != Hadoop
  • 20. Das CAP Theorem Availability Jede Anfrage bekommt eine Antwort Consistency Alle Knoten haben jederzeit die gleichen Informationen Partition Tolerance Trotz Knotenausfall funktioniert das System
  • 21. Überblick über NoSQL Systeme Availability Jeder Client kann immer schreiben und lesen C onsistency Alle Knoten haben jederzeit die gleichen Informationen Partition Tolerance Trotz Knotenausfall funktioniert das System
  • 24. ACID vs. BASE 1983 Atomicity RDBMS Consistency Isolation Durability
  • 25. ACID vs. BASE ACID ist ein gutes Konzept, aber es ist kein in Stein gemeißeltes Gesetz!
  • 26. ACID vs. BASE Basically Available Soft State 2008 NoSQL Eventually consistent
  • 27. ACID vs. BASE ACID BASE - - Starke Konsistenz Isolation Zwei-Phasen-Commit Komplexe Entwicklung Zuverlässiger Schwache Konsistenz Verfügbarkeit "Fire-and-forget" Leichtere Entwicklung Schneller
  • 29. MongoDB ist eine … • Dokumenten-basierte • Open Source • Performante • Flexible • Skalierbare • Hochverfügbare • Funktionsreiche …Datenbank
  • 30. Dokumenten-basierte Datenbank • Nicht im Sinne einer Datenbank für PDFoder Worddokumente…
  • 31. Open Source Datenbank • MongoDB ist ein Open Source Projekt • Auf GitHub – https://github.com/mongodb/mongo • Steht unter der AGPL Lizenz • Gestartet und gesponsert von MongoDB Inc. (früher: 10gen) • Kommerzielle Lizenzen sind verfügbar • Jeder darf mitmachen! – https://jira.mongodb.org
  • 33. Flexibles Schema MongoDB RDBMS { _id : ObjectId("4c4ba5e5e8aabf3"), employee_name: "Dunham, Justin", department : "Marketing", title : "Product Manager, Web", report_up: "Neray, Graham", pay_band: “C", benefits : [ { type : "Health", plan : "PPO Plus" }, { type : "Dental", plan : "Standard" } ] }
  • 34. Skalierbarkeit Auto-Sharding • Erhöhung der Kapazität wenn nötig • Ausgelegt für Commodity Hardware • Funktioniert mit Cloud-Architekturen
  • 35. Hochverfügbarkeit • Automatische Replikation und Failover • Unterstützung für mehrere Datenzentren • Ausgelegt auf möglichst einfachen Betrieb • Beständigkeit und Konsistenz der Daten
  • 41. Treiber & Shell Treiber verfügbar für die populärsten Programmiersprachen und Frameworks Java JavaScript Python Shell zur Interaktion mit der Datenbank Ruby Perl Haskell > db.collection.insert({product:“MongoDB”, type:“Document Database”}) > > db.collection.findOne() { “_id” : ObjectId(“5106c1c2fc629bfe52792e86”), “product” : “MongoDB” “type” : “Document Database” }
  • 42. NoSQL Trends Google Search LinkedIn Job Skills MongoDB Competitor 1 Competitor 2 Competitor 3 Competitor 4 Competitor 5 MongoDB Competitor 2 Competitor 1 Competitor 4 Competitor 3 All Others Jaspersoft Big Data Index Indeed.com Trends Top Job Trends Direct Real-Time Downloads MongoDB Competitor 1 Competitor 2 Competitor 3 1.HTML 5 2.MongoDB 3.iOS 4.Android 5.Mobile Apps 6.Puppet 7.Hadoop 8.jQuery 9.PaaS 10.Social Media
  • 45. Let’s have a look…
  • 46. Anlegen einer Datenbank // Anzeigen aller Datenbanken > show dbs digg 0.078125GB enron 1.49951171875GB // Wechsel in eine Datenbank > use blog // Erneutes Anzeigen aller Datenbanken > show dbs digg 0.078125GB enron 1.49951171875GB
  • 47. Anlegen einer Collection I // Anzeigen aller Collections > show collections // Einfügen eines Benutzers > db.user.insert( { name : “Sheldon“, mail : “sheldon@bigbang.com“ } ) Beim Einfügen erfolgt kein Feedback über den Erfolg der Operation, Abfrage über: db.runCommand( { getLastError: 1} )
  • 48. Anlegen einer Collection II // Anzeigen aller Collections > show collections system.indexes user // Anzeigen aller Datenbanken > show dbs blog 0.0625GB digg 0.078125GB enron 1.49951171875GB Datenbank und Collection werden automatisch beim ersten Insert anlegt.
  • 49. Lesen aus einer Collection // Anzeigen des ersten Dokuments > db.user.findOne() { "_id" : ObjectId("516684a32f391f3c2fcb80ed"), "name" : "Sheldon", "mail" : "sheldon@bigbang.com" } // Alle Dokumente einer Collection anzeigen > db.user.find() { "_id" : ObjectId("516684a32f391f3c2fcb80ed"), "name" : "Sheldon", "mail" : "sheldon@bigbang.com" }
  • 50. Filtern von Dokumenten // Filtern von bestimmten Dokumenten > db.user.find( { name : ”Penny” } ) { "_id" : ObjectId("5166a9dc2f391f3c2fcb80f1"), "name" : "Penny", "mail" : "penny@bigbang.com" } // Nur bestimmte Felder anzeigen > db.user.find( { name : ”Penny” }, {_id: 0, mail : 1} ) { "mail" : "sheldon@bigbang.com" }
  • 51. _id • _id ist der primäre Schlüssel in MongoDB • Index auf _id wird automatisch erzeugt • Wenn nicht anders angegeben, handelt es sich dabei um eine ObjectId • _id kann auch selbst beim Einfügen von Dokumenten vergeben werden, jeder einzigartige unveränderbare Wert kann dabei verwendet werden
  • 52. ObjectId • Eine ObjectId ist ein spezieller 12 Byte Wert • Ihre Einzigartigkeit über den gesamten Cluster ist durch die Zusammensetzung garantiert: ObjectId("50804d0bd94ccab2da652599") |-------------||---------||-----||----------| ts mac pid inc
  • 53. Cursor // Benutzen eines Cursors für die Dokumente > var myCursor = db.user.find( ) // Nächstes Dokument holen und Mail anzeigen > var myDocument = myCursor.hasNext() ? myCursor.next() : null; > if (myDocument) { printjson(myDocument.mail); } // Restliche Dokumente anzeigen > myCursor.forEach(printjson); In der Shell werden per Default 20 Dokumente angezeigt.
  • 54. Logische Verknüpfungen // Oder-Verknüpfung > db.user.find( {$or : [ { name : “Sheldon“ }, { mail : amy@bigbang.com } ] }) // Und-Verknüpfung > db.user.find( {$and : [ { name : “Sheldon“ }, { mail : amy@bigbang.com } ] })
  • 55. Ergebnismengen anpassen // Sortieren von Dokumenten > db.user.find().sort( { name : 1 } ) // Aufsteigend > db.user.find().sort( { name : -1 } ) // Absteigend // Ergebnismenge limitieren > db.user.find().limit(3) // Ergebnisdokumente überspringen > db.user.find().skip(2) // Kombination der Methoden > db.user.find().skip(2).limit(3)
  • 56. Update von Dokumenten I // Update der Mail-Adresse (So bitte nicht!) > db.user.update( { name : “Sheldon“ }, { mail : “sheldon@howimetyourmother.com“ } ) // Anzeige des Updates db.user.findOne() { "_id" : ObjectId("516684a32f391f3c2fcb80ed"), "mail" : "sheldon@howimetyourmother.com" } Aufpassen beim Update von Dokumenten!
  • 57. Löschen von Dokumenten // Löschen des Dokuments > db.user.remove( { mail : “sheldon@howimetyourmother.com“ } ) // Löschen aller Dokumente > db.user.remove() // Löschen von Dokumenten mittels Bedingung > db.user.remove( { mail : /.*mother.com$/ } ) // Löschen nur des ersten passenden Dokuments > db.user.remove( { mail : /.*.com$/ }, true )
  • 58. Update von Dokumenten II // Update der Mail-Adresse (Jetzt aber richtig!) > db.user.update( { name : “Sheldon“ }, { $set : { mail : “sheldon@howimetyourmother.com“ }}) // Anzeige des Updates db.user.find(name : “Sheldon“) { "_id" : ObjectId("5166ba122f391f3c2fcb80f5"), "mail" : "sheldon@howimetyourmother.com", "name" : "Sheldon" }
  • 59. Hinzufügen zu Arrays // Hinzufügen eines Arrays > db.user.update( {name : “Sheldon“ }, { $set : {enemies : [ { name : “Wil Wheaton“ }, { name : “Barry Kripke“ } ] }}) // Hinzufügen eines Wertes zum Array > db.user.update( { name : “Sheldon“}, { $push : {enemies : { name : “Leslie Winkle“} }})
  • 60. Löschen aus Arrays // Löschen eines Wertes aus dem Array > db.user.update( { name : “Sheldon“ }, {$pull : {enemies : {name : “Barry Kripke“ } }}) // Löschen des kompletten Feldes > db.user.update( {name : “Sheldon“}, {$unset : {enemies : 1}} )
  • 61. Einfügen eines Subdokuments // Hinzufügen eines Subdokuments > db.user.update( { name : “Sheldon“}, { $set : { mother :{ name : “Mary Cooper“, residence : “Galveston, Texas“, religion : “Evangelical Christian“ }}}) { "_id" : ObjectId("5166cf162f391f3c2fcb80f7"), "mail" : "sheldon@bigbang.com", "mother" : { "name" : "Mary Cooper", "residence" : "Galveston, Texas", "religion" : "Evangelical Christian" }, "name" : "Sheldon" }
  • 62. Abfragen auf Subdokumenten // Abfrage des Namens der Mutter > db.user.find( { name : “Sheldon“}, {“mother.name“ : 1 } ) { "_id" : ObjectId("5166cf162f391f3c2fcb80f7"), "mother" : { "name" : "Mary Cooper" } } Zusammengesetzte Feldnamen müssen in “…“ stehen!
  • 63. Übersicht über alle UpdateOperatoren Für Felder: $inc $rename $set $unset Bitweise: $bit Isolation: $isolated Für Arrays: $addToSet $pop $pullAll $pull $pushAll $push $each (Modifier) $slice (Modifier) $sort (Modifier)
  • 65. Das Aggregation Framework • Wurde eingeführt, um Aggregationen ohne Map/Reduce berechnen zu können • Framework von Methoden & Operatoren – Deklarativ – Kein eigener JavaScript-Code mehr nötig – Framework kann erweitert werden • Implementiert in C++ – Overhead der JavaScript-Engine wird vermieden – Höhere Performance
  • 67. Aggregation Pipeline • Verarbeitet einen Strom von Dokumenten – Eingabe ist eine Collection – Ausgabe ist ein Ergebnisdokument • Aneinanderreihung von PipelineOperatoren – Jede Stufe filtert oder transformiert die Dokumente – Ausgabedokumente einer Stufe sind die Eingabe- dokumente der nächsten Stufe
  • 68. Aufruf > db.tweets.aggregate( { $pipeline_operator_1 { $pipeline_operator_2 { $pipeline_operator_3 { $pipeline_operator_4 ... ); }, }, }, },
  • 69. Pipeline Operatoren // Alte Bekannte* // Neue Freunde $match $sort $limit $skip * Aus der Abfragefunktionalität $project $group $unwind
  • 70. Aggregation Framework I // Collection mit Tweets { "_id" : ObjectId("4fb9fb91d066d657de8d6f39"), "text" : "I can't wait for #BoardwalkEmpire", "in_reply_to_status_id" : null, "retweet_count" : null, "contributors" : null, "created_at" : "Thu Sep 02 18:11:24 +0000 2010", … "user" : { "friends_count" : 204, … "followers_count" : 24, "id" : 64054560, … }, …}
  • 71. Aggregation Framework II // Finde die Top-3-Twitterer nach Followern > db.tweets.aggregate( { $project : {name : "$user.name", follower_count : "$user.followers_count"}}, { $group : {_id : {name : "$name"}, follower_count : {$max : "$follower_count"}}}, { $sort : {follower_count : -1}}, { $limit: 3} );
  • 72. Aggregation Framework III // Finde die Top-3-Links aus Tweets > db.tweets.aggregate( { $project : {_id: 0, inhalt_des_tweets : "$text", links : "$entities.urls.url" } }, { $unwind : "$links" }, { $group : { _id : "$links", anzahl : {$sum : 1} } }, { $sort : {anzahl : -1} }, { $limit : 3 } );
  • 73. Was ist Map/Reduce? • Programmiermodel aus der funktionalen Welt • Framework zur – parallelen Verarbeitung – von großen Datenmengen – mittels verteilter Systeme • Populär geworden durch Google – Wird zur Berechnung des Suchindex verwendet, welcher Seiten zu Keywords zuordnet (Page Rank) – http://research.google.com/archive/mapreduce.html
  • 74. Map/Reduce mit MongoDB MongoDB map() Daten group(k) emit(k,v) Shard 1 • Iteriert über alle Dokumente sort(k) Shard 2 … Shard n reduce(k, values) finalize(k, v) k, v k, v • • Input = Output Kann mehrfach laufen
  • 75. Word Count: Problemstellung INPUT { MongoDB uses MapReduce } { There is a map phase } { There is a reduce phase } MAPPER GROUP/SORT REDUCER OUTPUT a: 2 is: 2 map: 1 Problem: Wie häufig kommt ein Wort in allen Dokumenten vor? mapreduce: 1 mongodb: 1 phase: 2 reduce: 1 there: 2 uses: 1
  • 76. Word Count: Tweets // Beispiel: Twitter-Datenbank mit Tweets > db.tweets.findOne() { "_id" : ObjectId("4fb9fb91d066d657de8d6f38"), "text" : "RT @RevRunWisdom: The bravest thing that men do is love women #love", "created_at" : "Thu Sep 02 18:11:24 +0000 2010", … "user" : { "friends_count" : 0, "profile_sidebar_fill_color" : "252429", "screen_name" : "RevRunWisdom", "name" : "Rev Run", }, …
  • 77. Word Count: Map Funktion // Map Funktion mit Bereinigung der Daten map = function() { this.text.split(' ').forEach(function(word) { // Entfernen von Whitespace word = word.replace(/s/g, ""); // Entfernen alle Non-Word-Characters word = word.replace(/W/gm,""); // Finally emit the cleaned up word if(word != "") { emit(word, 1) } }); };
  • 78. Word Count: Reduce Funktion // Reduce Funktion reduce = function(key, values) { return values.length; };
  • 79. Word Count: Aufruf // Anzeigen des Ergebnisses in der Konsole > db.tweets.mapReduce(map, reduce, { out : { inline : 1 } } ); // Speichern des Ergebnisses in einer Collection > db.tweets.mapReduce(map, reduce, { out : "tweets_word_count"} ); { "result" : "tweets_word_count", "timeMillis" : 19026, "counts" : { "input" : 53641, "emit" : 559217, "reduce" : 102057, "output" : 131003 }, "ok" : 1, }
  • 80. Word Count: Ergebnis // Ausgeben der 10 häufigsten Wörter in Tweets > db.tweets_word_count.find().sort({"value" : -1}).limit(10) { { { { { { { { { { "_id" "_id" "_id" "_id" "_id" "_id" "_id" "_id" "_id" "_id" : : : : : : : : : : "Miley", "value" : 31 } "mil", "value" : 31 } "andthenihitmydougie", "value" : 30 } "programa", "value" : 30 } "Live", "value" : 29 } "Super", "value" : 29 } "cabelo", "value" : 29 } "listen", "value" : 29 } "Call", "value" : 28 } "DA", "value" : 28 }
  • 82. Indexe in MongoDB sind B-Trees
  • 83. Abfragen, Einfügen und Löschen: O(log(n))
  • 84. Fehlende oder nicht optimale Indexe sind das häufigste vermeidbare MongoDB Performance-Problem
  • 85. Wie lege ich Indexe an? // Anlegen eines Index, wenn er noch nicht existiert > db.recipes.createIndex({ main_ingredient: 1 }) // Der Client merkt sich den Index und wirft keinen Fehler > db.recipes.ensureIndex({ main_ingredient: 1 }) * 1 für aufsteigend, -1 für absteigend
  • 86. Was kann indexiert werden? // Mehrere Felder (Compound Key Indexes) > db.recipes.ensureIndex({ main_ingredient: 1, calories: -1 }) // Arrays mit Werten (Multikey Indexes) { name: 'Chicken Noodle Soup’, ingredients : ['chicken', 'noodles'] } > db.recipes.ensureIndex({ ingredients: 1 })
  • 87. Was kann indexiert werden? // Subdokumente { name : 'Apple Pie', contributor: { name: 'Joe American', id: 'joea123' } } db.recipes.ensureIndex({ 'contributor.id': 1 }) db.recipes.ensureIndex({ 'contributor': 1 })
  • 88. Wie verwalte ich Indexe? // Auflisten aller Indexe einer Collection > db.recipes.getIndexes() > db.recipes.getIndexKeys() // Löschen eines Index > db.recipes.dropIndex({ ingredients: 1 }) // Löschen und Neuerzeugung aller Indexe db.recipes.reIndex() // Defaultindex auf _id
  • 89. Weitere Optionen • Unique Indexe – Nur eindeutige Werte erlaubt • Sparse Indexe – Für Felder, die nicht in allen Dokumenten vorkommen • Geospatial Indexe – Zur Modellierung von Geoinformationen • TTL Collections – Verfallen nach x Sekunden
  • 90. Unique Indexe // Der Name eines Rezepts muss eindeutig sein > db.recipes.ensureIndex( { name: 1 }, { unique: true } ) // Erzwingen eines Index auf einer Collection mit nicht eindeutigen // Namen – Die Duplikate werden gelöscht > db.recipes.ensureIndex( { name: 1 }, { unique: true, dropDups: true } ) * dropDups bitte mit sehr viel Vorsicht anwenden!
  • 91. Sparse Indexe // Nur Dokumente mit dem Feld calories werden indexiert > db.recipes.ensureIndex( { calories: -1 }, { sparse: true } ) // Kombination mit einem Unique Index möglich > db.recipes.ensureIndex( { name: 1 , calories: -1 }, { unique: true, sparse: true } ) * Fehlende Felder werden im Index als null gespeichert
  • 92. Geospatial Indexe // Hinzufügen von Längen- und Breitengraden { name: ‚codecentric Frankfurt’, loc: [ 50.11678, 8.67206] } // Indexierung der Koordinaten > db.locations.ensureIndex( { loc : '2d' } ) // Abfrage nach Orten in der Nähe von codecentric Frankfurt > db.locations.find({ loc: { $near: [ 50.1, 8.7 ] } })
  • 93. TTL Collections // Die Dokumente müssen ein Datum des Typs BSON UTC haben { ' submitted_date ' : ISODate('2012-10-12T05:24:07.211Z'), … } // Dokumente werden automatisch nach 'expireAfterSeconds' // Sekunden gelöscht > db.recipes.ensureIndex( { submitted_date: 1 }, { expireAfterSeconds: 3600 } )
  • 94. Limitierungen von Indexen • Collections können nicht mehr als 64 Indexe haben. • Indexschlüssel können nicht größer als 1024 Byte sein. • Der Name eines Index inklusive Namespace muss kleiner als 128 Zeichen sein. • Abfragen können nur einen Index verwenden – Ausnahme: Abfragen mit $or • Indexe verbrauchen Speichern und verlangsamen das Schreiben von Daten
  • 96. Vorgehensweise 1. Langsame Abfragen identifizieren 2. Mittels explain() mehr über die langsame Abfrage herausfinden 3. Anlegen der Indexe auf den abgefragten Feldern 4. Optimierung der Abfragen anhand der verwendeten Indexe
  • 97. 1. Langsame Abfragen identifizieren > db.setProfilingLevel( n , slowms=100ms ) n=0: Profiler abgeschaltet n=1: Protokollieren aller Abfragen langsamer als slowms n=2: Protokollieren aller Operationen > db.system.profile.find() * Die Collection profile ist eine Capped Collection und hat daher eine feste Anzahl von Einträgen
  • 98. 2. Benutzung von explain() > db.recipes.find( { calories: { $lt : 40 } } ).explain( ) { "cursor" : "BasicCursor" , "n" : 42, "nscannedObjects” : 53641 "nscanned" : 53641, ... "millis" : 252, ... } * Keine Verwendung von Plänen aus dem Cache und erneuten Ausführungen
  • 99. 2. Metriken des Executionplans I • Cursor – Der Typ des Cursors. BasicCursor bedeutet, dass kein Index benutzt wurde • n – Die Anzahl der passenden Dokumente • nscannedObjects – Die Anzahl der gescannten Dokumente • nscanned – Die Anzahl der untersuchten Einträge (Indexeinträge oder Dokumente)
  • 100. 2. Metriken des Executionplans II • millis – Ausführungszeit der Abfrage • Komplette Referenz unter – http://docs.mongodb.org/manual/reference/explain Das Verhältnis der gescannten zu den gefundenen Dokumenten sollte möglichst nahe an 1 sein!
  • 101. 3. Anlegen der Indexe auf den abgefragten Feldern
  • 102. 4. Optimierung der Abfragen anhand der verwendeten Indexe // Bei folgendem Index… > db.collection.ensureIndex({ a:1, b:1 , c:1, d:1 }) // // > > … können die folgenden Sortieroperationen und Abfragen den Index benutzen db.collection.find( ).sort({ a:1 }) db.collection.find( ).sort({ a:1, b:1 }) > db.collection.find({ a:4 }).sort({ a:1, b:1 }) > db.collection.find({ b:5 }).sort({ a:1, b:1 })
  • 103. 4. Optimierung der Abfragen anhand der verwendeten Indexe // Bei folgendem Index… > db.collection.ensureIndex({ a:1, b:1, c:1, d:1 }) // … können diese Abfragen ihn nicht verwenden > db.collection.find( ).sort({ b: 1 }) > db.collection.find({ b: 5 }).sort({ b: 1 })
  • 104. 4. Optimierung der Abfragen anhand der verwendeten Indexe // Bei folgendem Index… > db.recipes.ensureIndex({ main_ingredient: 1, name: 1 }) // … verwendet diese Abfrage nur Felder des Index > db.recipes.find( { main_ingredient: 'chicken’ }, { _id: 0, name: 1 } ) // Das Feld indexOnly bei explain() zeigt dies an > db.recipes.find( { main_ingredient: 'chicken' }, { _id: 0, name: 1 } ).explain() { "indexOnly": true, }
  • 105. Index manuell angeben // MongoDB mitteilen, welcher Index verwendet werden soll > db.recipes.find({ calories: { $lt: 1000 } } ).hint({ _id: 1 }) // Die Verwendung von Indexen ausschalten (z.B. zur Performance// messung > db.recipes.find( { calories: { $lt: 1000 } } ).hint({ $natural: 1 })
  • 107. Mehrere Index verwenden // MongoDB kann nur einen Index pro Abfrage verwenden > db.collection.ensureIndex({ a: 1 }) > db.collection.ensureIndex({ b: 1 }) // Nur einer der beiden obigen Indexe wird verwendet > db.collection.find({ a: 3, b: 4 })
  • 108. Zusammengesetzte Indexe // Zusammengesetzte Indexe sind im Allgemeinen sehr effektiv > db.collection.ensureIndex({ a: 1, b: 1, c: 1 }) // Aber nur wenn die Abfrage ein Präfix des Indexes ist… // Diese Abfrage kann den Index nicht effektiv verwenden db.collection.find({ c: 2 }) // …diese Abfrage hingegen schon db.collection.find({ a: 3, b: 5 })
  • 109. Indexe mit geringer Selektivität // Folgendes Feld hat nur sehr wenige eindeutige Werte > db.collection.distinct('status’) [ 'new', 'processed' ] // Ein Index auf diesem Feld bringt nur sehr wenig > db.collection.ensureIndex({ status: 1 }) > db.collection.find({ status: 'new' }) // Besser ist ein zusammengesetzter Index zusammen mit einem // anderen Feld > db.collection.ensureIndex({ status: 1, created_at: -1 }) > db.collection.find( { status: 'new' } ).sort({ created_at: -1 })
  • 110. Reguläre Ausdrücke & Indexe > db.users.ensureIndex({ username: 1 }) // Abfragen mit regulären Ausdrücken, die linksgebunden sind // können den Index verwenden > db.users.find({ username: /^joe smith/ }) // Generische Abfragen mit regulären Ausdrücken hingegen nicht… > db.users.find({username: /smith/ }) // Ebenso nicht schreibungsunabhängige Abfragen… > db.users.find({ username: /Joe/i })
  • 111. Negation // Bei Negationen können Indexe nicht verwendet werden > db.things.ensureIndex({ x: 1 }) // z.B. bei Abfragen mit not equal > db.things.find({ x: { $ne: 3 } }) // …oder Abfragen mit not in > db.things.find({ x: { $nin: [2, 3, 4 ] } }) // …oder Abfragen mit dem $not Operator > db.people.find({ name: { $not: 'John Doe' } })
  • 112. Konsistenz beim Schreiben und Lesen von Daten
  • 115. Write Concern - Schreibmodi • Bestätigung durch das Netzwerk • Bestätigung durch MongoDB • Bestätigung durch das Journal • Bestätigung durch Secondaries • Bestätigung durch Tagging
  • 116. Bestätigung durch das Netzwerk „Fire and forget“
  • 118. Bestätigung durch das Journal Wait for Journal Sync
  • 120. Tagging beim Schreiben • Verfügbar seit Version 2.0 • Ermöglicht stärkere Kontrolle woher Daten gelesen und wohin geschrieben werden • Jeder Knoten kann mehrere Tags haben – tags: {dc: "ny"} – tags: {dc: "ny", subnet: „192.168", rack: „row3rk7"} • Erlaubt das Anlegen für Regeln für das Write Concern pro Replikaset • Anpassung der Regeln ohne Codeänderung
  • 121. Beispiel für Tagging { _id : "mySet", members : [ {_id : 0, host : "A", tags : {"dc": "ny"}}, {_id : 1, host : "B", tags : {"dc": "ny"}}, {_id : 2, host : "C", tags : {"dc": "sf"}}, {_id : 3, host : "D", tags : {"dc": "sf"}}, {_id : 4, host : "E", tags : {"dc": "cloud"}}], settings : { getLastErrorModes : { allDCs : {"dc" : 3}, someDCs : {"dc" : 2}} } } > db.blogs.insert({...}) > db.runCommand({getLastError : 1, w : "someDCs"})
  • 122. Bestätigung durch alle Datenzentren Wait for Replication (Tagging)
  • 123. Setzen des Write Concerns // Wait for network acknowledgement > db.runCommand( { getLastError: 1, w: 0 } ) // Wait for error (Default) > db.runCommand( { getLastError: 1, w: 1 } ) // Wait for journal sync > db.runCommand( { getLastError: 1, w: 1, j: "true" } ) // Wait for replication > db.runCommand( { getLastError: 1, w: “majority" } ) // Mehrheit > db.runCommand( { getLastError: 1, w: 3 } ) // # der Secondaries
  • 124. Modi zum Lesen von Daten (Seit Version 2.2) • Nur Primary (primary) • Primary bevorzugt (primaryPreferred) • Nur Secondaries (secondary) • Secondaries bevorzugt (secondaryPreferred) • Nähester Knoten (Nearest) Falls mehr als ein Knoten möglich ist, wird immer der näheste Knoten zum Lesen der Daten verwendet. (Alle Modi außer Primary)
  • 130. Tagging beim Lesen • Ermöglicht eine individuelle Kontrolle woher Daten gelesen werden – z.B. { "disk": "ssd", "use": "reporting" } • Lässt sich mit den Standard-Lese-Modi kombinieren – Außer dem Modus „Nur Primary“
  • 131. Setzen der Read Preference // Nur Primary > cursor.setReadPref( “primary" ) // Primary bevorzugt > cursor.setReadPref( “primaryPreferred" ) …. // Nur Secondaries mit Tagging > cursor.setReadPref( “secondary“, [ rack : 2 ] ) Aufruf der Methode auf dem Cursor muss vor dem Lesen der Dokumente erfolgen
  • 132. Java API & Frameworks
  • 135. MongoDB Treiber • Ein Wire Protokoll für alle Programmiersprachen • Eine Implementierung des Treibers pro Sprache • Hauptaufgaben: – Konvertierung der sprachspezifischen Datenstrukturen nach BSON – Generierung der ObjectId für das Feld _id
  • 136. MongoDB Java Treiber • Ein JAR ohne weitere Abhängigkeiten: <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.11.3</version> </dependency> Verfügbar auf Github: https://github.com/mongodb/mongo-java-driver
  • 137. Verbindungsaufbau import com.mongodb.MongoClient; // Default: localhost:27017 mongo = new MongoClient(); // Replica set mongo = new MongoClient(Arrays.asList( new ServerAddress("replicant01", 10001), new ServerAddress("replicant02", 10002), new ServerAddress("replicant03", 10003) )); // Sharding: mongos server mongo = new MongoClient("mongos01", 4711);
  • 138. Zugriff auf Datenbank und Collection import com.mongodb.DB; import com.mongodb.DBCollection; DB db = mongo.getDB("test"); DBCollection collection = db.getCollection("foo");
  • 139. Dokument einfügen import com.mongodb.BasicDBObject; import com.mongodb.DBObject; // insert document DBObject doc = new BasicDBObject(); doc.put("date", new Date()); doc.put("i", 42); collection.insert(doc);
  • 140. Dokumente abfragen import com.mongodb.DBCursor; DBCursor cursor; cursor = collection.find(); // all documents // documents w/ {i: 42} cursor = collection.find( new BasicDBObject("i", 42) ); document = cursor.next(); ...
  • 141. Beispiel: Bestellung > db.order.find( {"items.quantity": ? } )
  • 142. Beispiel: Bestellung I DB db = mongo.getDB("test"); DBCollection collection = db.getCollection("order"); DBObject order; List<DBObject> items = new ArrayList<DBObject>(); DBObject item; // order order = new BasicDBObject(); order.put("date", new Date()); order.put("custInfo" , „Sheldon Cooper"); // items item = new BasicDBObject(); item.put("quantity", 1); item.put("price", 47.11); item.put("desc", "Item #1"); items.add(item); item = new BasicDBObject(); item.put("quantity", 2); item.put("price", 42.0); item.put("desc", "Item #2"); items.add(item); order.put("items", items); collection.insert(order);
  • 143. Beispiel: Bestellung II DB db = mongo.getDB("test"); DBCollection collection = db.getCollection("order"); DBObject query; DBObject document; DBCursor cursor; query = new BasicDBObject("items.quantity", 2); cursor = collection.find(query); while ( cursor.hasNext() ) { document = cursor.next(); println(document); }
  • 144. Jongo
  • 145. Kurzüberblick über Jongo Entwickler Lizenz Dokumentation Hauptmerkmale Benoît Guérout, Yves Amsellem Apache License, Version 2.0 http://jongo.org/ • Object/Document Mapping • Eigene Query API
  • 146. Query in Java as in Mongo Shell
  • 147. Jongo: Object Mapping public class Order { private ObjectId id; private Date date; @JsonProperty("custInfo") private String customerInfo; List<Item> items; … } public class Item { private int quantity; private double price; @JsonProperty("desc") private String description; … }
  • 148. Jongo: Abfragen // Java driver API MongoClient mc = new MongoClient(); DB db = mc.getDB("odm_jongo"); // Jongo API entry point Jongo jongo = new Jongo(db); MongoCollection orders = jongo.getCollection("order"); // no DAO needed Iterable<Order> result = orders.find("{"items.quantity": #}", 2).as(Order.class); // supports projection Iterable<X> result = orders.find().fields("{_id:0, date:1, custInfo:1}").as(X.class);
  • 150. Kurzüberblick über Morphia Entwickler Lizenz Dokumentation Scott Hernandez, James Green Apache License, Version 2.0 https://github.com/jmkgreen/morph ia/wiki/Overview Hauptmerkmale • Object/Document Mapping • Eigene Query API • Unterstützung für DAO‘s
  • 151. Morphia: Object Mapping public class Order { @Id private ObjectId id; private Date date; @Property("custInfo") private String customerInfo; @Embedded List<Item> items; ... } public class Item { private int quantity; private double price; @Property("desc") private String description; ... }
  • 152. Morphia: Abfragen public class OrderDao extends BasicDAO<Order, ObjectId> { List<Order> findByItemsQuantity(int quantity) { return find( createQuery().filter("items.quantity", quantity)) .asList(); } List<Order> findByItemsPriceGreaterThan(double price) { return find( createQuery().field("items.price").greaterThan(price) ) .asList(); } … }
  • 153. Morphia: Eigene Syntax für Abfragen Morphia Mongo Query = !=, <> >, <, >=,<= in, nin elem … $eq $neq $gt, $lt, $gte, $lte $in, $nin $elemMatch ….
  • 155. Kurzüberblick über Spring Data MongoDB Hersteller Lizenz Dokumentation VMware / SpringSource Apache License, Version 2.0 http://www.springsource.org/spring -data/mongodb Hauptmerkmale • Repository Support • Object/Document Mapping • Templating
  • 156. Spring Data CrudRepository Spring Data JPA PagingAndSortingRepository Spring Data Neo4j MongoReposito ry GraphRepos itory MongoT em plate JpaRepository Spring Data MongoDB Neo4jTemplate Em bedded JPA JDBC RDBMS Spring Data … RES T Mongo Java Driver Mongo DB Neo4j … Einheitliche Architektur für relationale Datenbanken sowie für unterstützte NoSQL-Stores
  • 157. Spring Data MongoDB • Repository Support – Abfragen werden aus den Methodensignaturen erstellt – Annotationen für Abfragen • Object-Document-Mapping – Annotationen: @Document, @Field, @Index, … – Klassen werden auf Collections gemappt, Javaobjekte auf Dokumente • Templating – – – – Abstraktion der Ressourcen Konfigurierbarkeit der Verbindungen zu MongoDB Abdeckung des Lebenszyklus einer Collection Unterstützung für Map/Reduce & Aggregation Framework
  • 158. Spring Data MongoDB: Konfiguration <!-- Connection to MongoDB server --> <mongo:db-factory host="localhost" port="27017" dbname="test" /> <!-- MongoDB Template --> <bean id="mongoTemplate, class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean> <!-- Package w/ automagic repositories --> <mongo:repositories base-package="mongodb" />
  • 159. Spring Data MongoDB: Template <mongo:mongo host="${mongo.host}" port="${mongo.port}"> <mongo:options connections-per-host="${mongo.connectionsPerHost}„ threads-allowed-to-block-for-connection multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}„ connect-timeout="${mongo.connectTimeout}„ max-wait-time="${mongo.maxWaitTime}„ auto-connect-retry="${mongo.autoConnectRetry}„ socket-keep-alive="${mongo.socketKeepAlive}„ socket-timeout="${mongo.socketTimeout}„ slave-ok="${mongo.slaveOk}„ write-number="1„ write-timeout="0„ write-fsync="true"/> </mongo:mongo> <mongo:db-factory dbname= "test" mongo-ref="mongo"/>
  • 160. Spring Data MongoDB: Object Mapping public class Order { @Id private String id; private Date date; @Field("custInfo") private String customerInfo; List<Item> items; ... } public class Item { private int quantity; private double price; @Field("desc") private String description; ... }
  • 161. Spring Data MongoDB: Repository Support public interface OrderRepository extends MongoRepository<Order, String> { List<Order> findByItemsQuantity(int quantity); List<Order> findByItemsPriceGreaterThan(double price); }
  • 162. Spring Data MongoDB: Zusätzliche Unterstützung für… • Map/Reduce & das Aggregation Framework • Das Management von Indexen • Große Dateien mittels GridFS • Geoinformatische Indexe und Abfragen • Optimistisches Locking
  • 164. Kurzüberblick über Hibernate OGM MongoDB Hersteller Lizenz Dokumentation JBoss / Redhat GNU LGPL, Version 2.1 http://www.hibernate.org/subproject s/ogm.html Hauptmerkmale • JPA API (Teilweise) • JPQL Query Language
  • 165. Hibernate OGM • Implementiert ein Subset der JPA API • JP-QL Anfragen werden in native Datenbankabfragen übersetzt • Unterstützt Infinispan, EhCache, MongoDB
  • 167. Hibernate OGM MongoDB: Konfiguration <persistence version="2.0" …> <persistence-unit name="primary"> <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider> <class>hibernate.Order</class> <class>hibernate.Item</class> <properties> <property name="hibernate.ogm.datastore.provider" value="org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastorePr ovider"/> <property name="hibernate.ogm.mongodb.database" value=„odm"/> <property name="hibernate.ogm.mongodb.host" value=„localhost"/> <property name="hibernate.ogm.mongodb.port" value=„27017"/> </properties> </persistence-unit> </persistence>
  • 168. Hibernate OGM MongoDB: Object Mapping @Entity @NamedQuery( name="byItemsQuantity", query = "SELECT o FROM Order o JOIN o.items i WHERE i.quantity = :quantity" ) public class Order { @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") @Id private String id; private Date date; @Column(name = "custInfo") private String customerInfo; @ElementCollection private List<Item> items; @Embeddable public class Item { private int quantity; private double price; @Column(name="desc") private String description; ...
  • 169. Hibernate OGM MongoDB: Aktueller Status • Frühes Beta-Stadium • Aktuell nur Speichern / Mergen / Löschen von Daten möglich • Noch keine Unterstützung für Abfragen • Benutzt eine relationale API
  • 170. Not yet ready for prime time…
  • 172. Was sollte ich einsetzen? - „Ready for production“ JPA Hibernate OGM Spring Data MongoDB - Frühes Betastadium - Diskrepanz in API - Aktive Community - Ältestes Framework - Nicht so mächtig wie Spring Morphia Der „bessere“ Treiber Jongo JDBC MongoDB Java Driver - „Ready for production“ - Von MongoDB Inc. unterstützt MongoDB
  • 176. So Long, and Thanks for All the Fish!