SlideShare a Scribd company logo
MongoDB - Back to Basics - La tua prima Applicazione
Back to Basics 2017 : Webinar 2
La Tua Prima Applicazione
Massimo Brignoli
Principal Solution Architect
MongoDB
massimo@mongodb.com
@massimobrignoli
V1.0
3
Riassunto della Parte 1
• Perché esistono i NoSQL
• I vari tipi di database NoSQL
• Le caratteristiche principali di MongoDB
4
Agenda
• I concetti base
• Installare MongoDB
• Costruire un’applicazione base di blogging
• Aggiungere gli indici
• Ottimizzare le query con l’explain
5
Concetti
Relational MongoDB
Database Database
Table Collection
Row Document
Index Index
Join Lookup
Foreign Key Reference
Multi-table transaction Single document transaction
6
Document Store
{
name : “Massimo Brignoli”,
title : “Principal Solutions Architect”,
Address : {
address1 : “Via Paleocapa 7”,
address2 : “c/o Regus”,
zipcode: “20121”,
}
expertise: [ “MongoDB”, “Python”, “Javascript” ],
employee_number : 334,
location : [ 53.34, -6.26 ]
}
7
I Documenti di MongoDB Sono Tipizzati
{
name : “Massimo Brignoli”,
title : “Principal Solutions Architect”,
Address : {
address1 : “Via Paleocapa 7”,
address2 : “c/o Regus”,
zipcode: “20121”,
}
expertise: [ “MongoDB”, “Python”, “Javascript” ],
employee_number : 334,
location : [ 53.34, -6.26 ]
}
Strings
Nested Document
Array
Integer
Geo-spatial Coordinates
8
MongoDB Drivers
http://bsonspec.org/spec.html
9
Installare MongoDB
$ curl -O https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-3.4.1.tgz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 60.9M 100 60.9M 0 0 2730k 0 0:00:22 0:00:22 --:--:-- 1589k
$ tar xzvf mongodb-osx-x86_64-3.2.6.tgz
x mongodb-osx-x86_64-3.2.6/README
x mongodb-osx-x86_64-3.2.6/THIRD-PARTY-NOTICES
x mongodb-osx-x86_64-3.2.6/MPL-2
x mongodb-osx-x86_64-3.2.6/GNU-AGPL-3.0
x mongodb-osx-x86_64-3.2.6/bin/mongodump
x mongodb-osx-x86_64-3.2.6/bin/mongorestore
x mongodb-osx-x86_64-3.2.6/bin/mongoexport
x mongodb-osx-x86_64-3.2.6/bin/mongoimport
x mongodb-osx-x86_64-3.2.6/bin/mongostat
x mongodb-osx-x86_64-3.2.6/bin/mongotop
x mongodb-osx-x86_64-3.2.6/bin/bsondump
x mongodb-osx-x86_64-3.2.6/bin/mongofiles
x mongodb-osx-x86_64-3.2.6/bin/mongooplog
x mongodb-osx-x86_64-3.2.6/bin/mongoperf
x mongodb-osx-x86_64-3.2.6/bin/mongosniff
x mongodb-osx-x86_64-3.2.6/bin/mongod
x mongodb-osx-x86_64-3.2.6/bin/mongos
x mongodb-osx-x86_64-3.2.6/bin/mongo
$ ln -s mongodb-osx-x86_64-3.2.6 mongodb
10
Eseguire mongod
JD10Gen:mongodb mbrignoli$ ./bin/mongod --dbpath /data/b2b
2016-05-23T19:21:07.767+0100 I CONTROL [initandlisten] MongoDB starting : pid=49209 port=27017 dbpath=/data/b2b 64-
bit host=JD10Gen.local
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] db version v3.4.1
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] git version: 05552b562c7a0b3143a729aaa0838e558dc49b25
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] allocator: system
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] modules: none
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] build environment:
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] distarch: x86_64
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] target_arch: x86_64
2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] options: { storage: { dbPath: "/data/b2b" } }
2016-05-23T19:21:07.769+0100 I - [initandlisten] Detected data files in /data/b2b created by the 'wiredTiger'
storage engine, so setting the active storage engine to 'wiredTiger'.
2016-05-23T19:21:07.769+0100 I STORAGE [initandlisten] wiredtiger_open config:
create,cache_size=4G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true
,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB)
,statistics_log=(wait=0),
2016-05-23T19:21:08.837+0100 I CONTROL [initandlisten]
2016-05-23T19:21:08.838+0100 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256,
should be at least 1000
2016-05-23T19:21:08.840+0100 I NETWORK [HostnameCanonicalizationWorker] Starting hostname canonicalization worker
2016-05-23T19:21:08.840+0100 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory
'/data/b2b/diagnostic.data'
2016-05-23T19:21:08.841+0100 I NETWORK [initandlisten] waiting for connections on port 27017
2016-05-23T19:21:09.148+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:59213 #1 (1 connection now
open)
11
Connettersi Via Shell
$ ./bin/mongo
MongoDB shell version: 3.4.1
connecting to: test
Server has startup warnings:
2016-05-17T11:46:03.516+0100 I CONTROL [initandlisten]
2016-05-17T11:46:03.516+0100 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. Number of
files is 256, should be at least 1000
>
12
Inserire il Vostro Primo Record
> show databases
local 0.000GB
> use test
switched to db test
> show databases
local 0.000GB
> db.demo.insert( { "key" : "value" } )
WriteResult({ "nInserted" : 1 })
> show databases
local 0.000GB
test 0.000GB
> show collections
demo
> db.demo.findOne()
{ "_id" : ObjectId("573af7085ee4be80385332a6"), "key" : "value" }
>
13
Object ID
573af7085ee4be80385332a6
TS------ID----PID-Count-
14
Usare Compass
15
Una Semplice Applicazione di Blog
• Creiamo una applicazione di blogging con questi dati:
– Articles
– Users
– Comments
16
Un Tipico Diagramma Entità - Relazioni
17
In MongoDB possiamo farlo in modo organico
> use blog
switched to db blog
> db.users.insert( { "username" : ”mbrignoli", "password" : "top secret", "lang" : ”IT" } )
WriteResult({ "nInserted" : 1 })
> db.users.findOne()
{
"_id" : ObjectId("573afff65ee4be80385332a7"),
"username" : ”mbrignoli",
"password" : "top secret",
"lang" : ”IT"
}
18
Come lo facciamo in un programma?
'''
Created on 17 May 2016
@author: mbrignoli
'''
import pymongo
#
# client defaults to localhost and port 27017. eg MongoClient('localhost', 27017)
client = pymongo.MongoClient()
blogDatabase = client[ "blog" ]
usersCollection = blogDatabase[ "users" ]
usersCollection.insert_one( { "username" : ”mbrignoli",
"password" : "top secret",
"lang" : “IT" })
user = usersCollection.find_one()
print( user )
19
Passiamo agli Articles
…
articlesCollection = blogDatabase[ "articles" ]
author = ”mbrignoli"
article = { "title" : ”Questo è il mio primo post",
"body" : ”Questo è il contenuto del mio post, posso aggiungere un sacco di testo qua.",
"author" : author,
"tags" : [ ”massimo", "general", ”Italia", "admin" ]
}
#
# Lets check if our author exists
#
if usersCollection.find_one( { "username" : author }) :
articlesCollection.insert_one( article )
else:
raise ValueError( "Author %s does not exist" % author )
20
Creiamo un nuovo tipo di articolo
#
# Lets add a new type of article with a posting date and a section
#
author = ”mbrignoli"
title = ”Questo è un post su MongoDB"
newPost = { "title" : title,
"body" : ”MongoDB è il database NoSQL più popolare del mondo. E’ un database a
documenti.",
"author" : author,
"tags" : [ ”massimo", "mongodb", ”Italia" ],
"section" : "technology",
"postDate" : datetime.datetime.now(),
}
#
# Lets check if our author exists
#
if usersCollection.find_one( { "username" : author }) :
articlesCollection.insert_one( newPost )
21
Facciamo un po’di articoli
import pymongo
import string
import datetime
import random
def randomString( size, letters = string.letters ):
return "".join( [random.choice( letters ) for _ in xrange( size )] )
client = pymongo.MongoClient()
def makeArticle( count, author, timestamp ):
return { "_id" : count,
"title" : randomString( 20 ),
"body" : randomString( 80 ),
"author" : author,
"postdate" : timestamp }
def makeUser( username ):
return { "username" : username,
"password" : randomString( 10 ) ,
"karma" : random.randint( 0, 500 ),
"lang" : "EN" }
22
Facciamo un po’di articoli
blogDatabase = client[ "blog" ]
usersCollection = blogDatabase[ "users" ]
articlesCollection = blogDatabase[ "articles" ]
bulkUsers = usersCollection.initialize_ordered_bulk_op()
bulkArticles = articlesCollection.initialize_ordered_bulk_op()
ts = datetime.datetime.now()
for i in range( 1000000 ) :
#username = randomString( 10, string.ascii_uppercase ) + "_" + str( i )
username = "USER_" + str( i )
bulkUsers.insert( makeUser( username ) )
ts = ts + datetime.timedelta( seconds = 1 )
bulkArticles.insert( makeArticle( i, username, ts ))
if ( i % 500 == 0 ) :
bulkUsers.execute()
bulkArticles.execute()
bulkUsers = usersCollection.initialize_ordered_bulk_op()
bulkArticles = articlesCollection.initialize_ordered_bulk_op()
bulkUsers.execute()
bulkArticles.execute()
23
Trovare un Utente
> db.users.findOne()
{
"_id" : ObjectId("5742da5bb26a88bc00e941ac"),
"username" : USER_1,
"lang" : "EN",
"password" : "vTlILbGWLt",
"karma" : 448
}
> db.users.find( { "username" : ”USER_45" } ).pretty()
{
"_id" : ObjectId("5742da5bb26a88bc00e94206"),
"username" : ”USER_45",
"lang" : "EN",
"password" : "GmRLnCeKVp",
"karma" : 284
}
24
Trovare gli Utenti con un alto Karma
> db.users.find( { "karma" : { $gte : 450 }} ).pretty()
{
"_id" : ObjectId("5742da5bb26a88bc00e941ae"),
"username" : "USER_1",
"lang" : "EN",
"password" : "bCSKSKvUeb",
"karma" : 487
}
{
"_id" : ObjectId("5742da5bb26a88bc00e941e4"),
"username" : »USER_28",
"lang" : "EN",
"password" : "HAWpiATCBN",
"karma" : 473
}
{
…
25
Usare la Projection
> db.users.find( { "karma" : { "$gte" : 450 }}, { "_id" : 0, "username" : 1 , "karma" : 1 })
{ "username" : "USER_1", "karma" : 461 }
{ "username" : "USER_3", "karma" : 494 }
{ "username" : "USER_20", "karma" : 464 }
{ "username" : "USER_34", "karma" : 475 }
{ "username" : "USER_46", "karma" : 462 }
{ "username" : "USER_47", "karma" : 486 }
{ "username" : "USER_48", "karma" : 488 }
{ "username" : "USER_49", "karma" : 452 }
{ "username" : "USER_61", "karma" : 483 }
{ "username" : "USER_73", "karma" : 452 }
{ "username" : "USER_80", "karma" : 494 }
{ "username" : "USER_87", "karma" : 497 }
…
26
Aggiornare un Articolo per Aggiungere Commenti
> db.articles.find( { "_id" : 18 } ).pretty()
{
"_id" : 18,
"body" :
"nTzOofOcnHKkJxpjKAyqTTnKZMFzzkWFeXtBRuEKsctuGBgWIrEBrYdvFIVHJWaXLUTVUXblOZZgUq
Wu",
"postdate" : ISODate("2016-05-23T12:02:46.830Z"),
"author" : “USER_18",
"title" : "CPMaqHtAdRwLXhlUvsej"
}
> db.articles.update( { _id : 18 }, { $set : { comments : [] }} )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
27
Aggiornare un Articolo per Aggiungere Commenti
> db.articles.find( { _id :18 } ).pretty()
{
"_id" : 18,
"body" :
"KmwFSIMQGcIsRNTDBFPuclwcVJkoMcrIPwTiSZDYyatoKzeQiKvJkiVSrndXqrALVIYZxGpaMjucgX
UV",
"postdate" : ISODate("2016-05-23T16:04:39.497Z"),
"author" : "USER_18",
"title" : "wTLreIEyPfovEkBhJZZe",
"comments" : [ ]
}
>
28
Aggiornare un Articolo per Aggiungere Commenti
> db.articles.update( { _id : 18 }, { $push : { comments : { username : ”max", comment :
"hey first post" }}} )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.articles.find( { _id :18 } ).pretty()
{
"_id" : 18,
"body" :
"KmwFSIMQGcIsRNTDBFPuclwcVJkoMcrIPwTiSZDYyatoKzeQiKvJkiVSrndXqrALVIYZxGpaMjucgXUV",
"postdate" : ISODate("2016-05-23T16:04:39.497Z"),
"author" : "USER_18",
"title" : "wTLreIEyPfovEkBhJZZe",
"comments" : [
{
"username" : ”max",
"comment" : "hey first post"
}
]
}
>
29
Cancellare un articolo
> db.articles.remove( { "_id" : 25 } )
WriteResult({ "nRemoved" : 1 })
> db.articles.remove( { "_id" : 25 } )
WriteResult({ "nRemoved" : 0 })
> db.articles.remove( { "_id" : { $lte : 5 }} )
WriteResult({ "nRemoved" : 6 })
• Le cancellazioni lasciare degli spazi vuoti
• Gli spazi vuoti vengono riutilizzati
30
Riguardiamo gli utenti e gli articoli
> db.users.findOne()
{
"_id" : ObjectId("57431c07b26a88bf060e10cb"),
"username" : "USER_0",
"lang" : "EN",
"password" : "kGIxPxqKGJ",
"karma" : 266
}
> db.articles.findOne()
{
"_id" : 0,
"body" :
"hvJLnrrfZQurmtjPfUWbMhaQWbNjXLzjpuGLZjsxHXbUycmJVZTeOZesTnZtojThrebRcUoiYwivjpwG"
,
"postdate" : ISODate("2016-05-23T16:04:39.246Z"),
"author" : "USER_0",
"title" : "gpNIoPxpfTAxWjzAVoTJ"
}
>
31
Explain: Trova un utente
> db.users.find( { "username" : "USER_99" } ).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "blog.users",
"indexFilterSet" : false,
"parsedQuery" : {
"username" : {
"$eq" : "USER_99"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"username" : {
"$eq" : "USER_99"
}
},
"direction" : "forward"
},
},
}
32
Explain: Trova un Utente – execution stats
> db.users.find( { "username" : "USER_99" } ).explain( "executionStats" ).executionStats
{
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 412,
"totalKeysExamined" : 0,
"totalDocsExamined" : 1000000,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"username" : {
"$eq" : "USER_99"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 302,
"works" : 1000002,
"advanced" : 1,
"needTime" : 1000000,
"needYield" : 0,
"saveState" : 7823,
"restoreState" : 7823,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 1000000
}
}
33
Abbiamo Bisogno di un Indice
> db.users.createIndex( { username : 1 } )
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>
34
Overview degli Indici
• Parametri
– Background : Crea un indice in background senza lockare il db
– Unique : Tutte le chiavi nella collection devono essere uniche.
– Name : Da un nome all’indice, altrimenti il nome sarà generato automaticamente
• Cancellare un indice
– db.users.dropIndex({ “username” : 1 })
• Mostrare tutti gli indici
– db.users.getIndexes()
35
Passaggi nell’esecuzione del Query Plan
• COLLSCAN : full scan di una collection
• IXSCAN : Scansione di un indice
• FETCH : per leggere i documenti
• SHARD_MERGE : Per unire i risultati dagli shard
36
Aggiungere un Indice
> db.users.find( {"username" : "USER_999999”} ).explain("executionStats”).executionStats
{
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 0,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
…
37
Execution stage
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"docsExamined" : 1,,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"keyPattern" : {
"username" : 1
},
"indexName" : "username_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"username" : [
"["USER_999999", "USER_999999"]"
]
},
"keysExamined" : 1,
"seenInvalidated" : 0
}
}
}
38
Cosa Abbiamo Imparato
• Come creare un database e una collection
• Come inserire contenuto in una collection
• Come interrogare una collection
• Come aggiornare un documento
• Come cancellare un documento
• Come controllare l’efficienza di una query
• Come aggiungere un indice
• Come controllare che un indice sia usato durante una
query
39
Prossimo Webinar : Introduzione ai Replica Sets
• Come assicurare che I vostri dati sia durabili
• Come recuperare da failure automaticamente
• Come scrivere codice sicuro lato clienti
Martedì, 20 Giugno 2017, 11:00 CET.
Q&A
Grazie!

More Related Content

PPTX
MongoDB 3.2 - Analytics
PPTX
Back to basics Italian webinar 2 Mia prima applicazione MongoDB
PPTX
Operational Intelligence with MongoDB Webinar
PPTX
Back to Basics: My First MongoDB Application
PDF
Hadoop - MongoDB Webinar June 2014
PDF
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
PDF
MongoDB Europe 2016 - Debugging MongoDB Performance
PPTX
Back to Basics, webinar 2: La tua prima applicazione MongoDB
MongoDB 3.2 - Analytics
Back to basics Italian webinar 2 Mia prima applicazione MongoDB
Operational Intelligence with MongoDB Webinar
Back to Basics: My First MongoDB Application
Hadoop - MongoDB Webinar June 2014
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
MongoDB Europe 2016 - Debugging MongoDB Performance
Back to Basics, webinar 2: La tua prima applicazione MongoDB

What's hot (19)

PDF
MongoDB for Analytics
PPTX
Getting Started with MongoDB and NodeJS
PPTX
Webinar: General Technical Overview of MongoDB for Dev Teams
PPTX
Back to Basics Webinar 5: Introduction to the Aggregation Framework
PPTX
2014 bigdatacamp asya_kamsky
PPTX
Back to Basics Webinar 2: Your First MongoDB Application
PPTX
How to leverage what's new in MongoDB 3.6
PPTX
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
PPTX
MongoDB - Aggregation Pipeline
PPTX
MongoDB San Francisco 2013: Hash-based Sharding in MongoDB 2.4 presented by B...
ODP
2011 Mongo FR - Indexing in MongoDB
PDF
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
PPTX
Back to Basics Webinar 3: Schema Design Thinking in Documents
PPTX
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
PPTX
Introduction to MongoDB and Hadoop
PPTX
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
PDF
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
PPTX
Agg framework selectgroup feb2015 v2
PPTX
Webinar: Exploring the Aggregation Framework
MongoDB for Analytics
Getting Started with MongoDB and NodeJS
Webinar: General Technical Overview of MongoDB for Dev Teams
Back to Basics Webinar 5: Introduction to the Aggregation Framework
2014 bigdatacamp asya_kamsky
Back to Basics Webinar 2: Your First MongoDB Application
How to leverage what's new in MongoDB 3.6
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
MongoDB - Aggregation Pipeline
MongoDB San Francisco 2013: Hash-based Sharding in MongoDB 2.4 presented by B...
2011 Mongo FR - Indexing in MongoDB
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
Back to Basics Webinar 3: Schema Design Thinking in Documents
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
Introduction to MongoDB and Hadoop
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
Agg framework selectgroup feb2015 v2
Webinar: Exploring the Aggregation Framework
Ad

Similar to MongoDB - Back to Basics - La tua prima Applicazione (20)

PPTX
Back to Basics 2017 - Your First MongoDB Application
PPTX
Back to Basics Webinar 2 - Your First MongoDB Application
PDF
Back to Basics 2017: Mí primera aplicación MongoDB
PPTX
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
PDF
Building Apps with MongoDB
PPTX
Webinar: Build an Application Series - Session 2 - Getting Started
PDF
Fun Teaching MongoDB New Tricks
PPTX
Marc s01 e02-crud-database
PDF
The emerging world of mongo db csp
PPTX
Building a Scalable Inbox System with MongoDB and Java
ODP
Mongo db dla administratora
PDF
MongoDB Performance Tuning
PDF
Starting with MongoDB
PPTX
S01 e01 schema-design
PPTX
A miało być tak... bez wycieków
PDF
Webinar: Was ist neu in MongoDB 2.4
PDF
MongoDB With Style
PPTX
Eagle6 mongo dc revised
PPTX
Eagle6 Enterprise Situational Awareness
PDF
Lab pratico per la progettazione di soluzioni MongoDB in ambito Internet of T...
Back to Basics 2017 - Your First MongoDB Application
Back to Basics Webinar 2 - Your First MongoDB Application
Back to Basics 2017: Mí primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Building Apps with MongoDB
Webinar: Build an Application Series - Session 2 - Getting Started
Fun Teaching MongoDB New Tricks
Marc s01 e02-crud-database
The emerging world of mongo db csp
Building a Scalable Inbox System with MongoDB and Java
Mongo db dla administratora
MongoDB Performance Tuning
Starting with MongoDB
S01 e01 schema-design
A miało być tak... bez wycieków
Webinar: Was ist neu in MongoDB 2.4
MongoDB With Style
Eagle6 mongo dc revised
Eagle6 Enterprise Situational Awareness
Lab pratico per la progettazione di soluzioni MongoDB in ambito Internet of T...
Ad

Recently uploaded (20)

PDF
Encapsulation theory and applications.pdf
PDF
Zenith AI: Advanced Artificial Intelligence
PDF
Mushroom cultivation and it's methods.pdf
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PPTX
TLE Review Electricity (Electricity).pptx
PDF
A comparative analysis of optical character recognition models for extracting...
PPTX
Tartificialntelligence_presentation.pptx
PDF
Hybrid model detection and classification of lung cancer
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
Getting Started with Data Integration: FME Form 101
PDF
Enhancing emotion recognition model for a student engagement use case through...
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
project resource management chapter-09.pdf
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Unlocking AI with Model Context Protocol (MCP)
Encapsulation theory and applications.pdf
Zenith AI: Advanced Artificial Intelligence
Mushroom cultivation and it's methods.pdf
Web App vs Mobile App What Should You Build First.pdf
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
TLE Review Electricity (Electricity).pptx
A comparative analysis of optical character recognition models for extracting...
Tartificialntelligence_presentation.pptx
Hybrid model detection and classification of lung cancer
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
MIND Revenue Release Quarter 2 2025 Press Release
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Group 1 Presentation -Planning and Decision Making .pptx
Getting Started with Data Integration: FME Form 101
Enhancing emotion recognition model for a student engagement use case through...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
project resource management chapter-09.pdf
cloud_computing_Infrastucture_as_cloud_p
Unlocking AI with Model Context Protocol (MCP)

MongoDB - Back to Basics - La tua prima Applicazione

  • 2. Back to Basics 2017 : Webinar 2 La Tua Prima Applicazione Massimo Brignoli Principal Solution Architect MongoDB massimo@mongodb.com @massimobrignoli V1.0
  • 3. 3 Riassunto della Parte 1 • Perché esistono i NoSQL • I vari tipi di database NoSQL • Le caratteristiche principali di MongoDB
  • 4. 4 Agenda • I concetti base • Installare MongoDB • Costruire un’applicazione base di blogging • Aggiungere gli indici • Ottimizzare le query con l’explain
  • 5. 5 Concetti Relational MongoDB Database Database Table Collection Row Document Index Index Join Lookup Foreign Key Reference Multi-table transaction Single document transaction
  • 6. 6 Document Store { name : “Massimo Brignoli”, title : “Principal Solutions Architect”, Address : { address1 : “Via Paleocapa 7”, address2 : “c/o Regus”, zipcode: “20121”, } expertise: [ “MongoDB”, “Python”, “Javascript” ], employee_number : 334, location : [ 53.34, -6.26 ] }
  • 7. 7 I Documenti di MongoDB Sono Tipizzati { name : “Massimo Brignoli”, title : “Principal Solutions Architect”, Address : { address1 : “Via Paleocapa 7”, address2 : “c/o Regus”, zipcode: “20121”, } expertise: [ “MongoDB”, “Python”, “Javascript” ], employee_number : 334, location : [ 53.34, -6.26 ] } Strings Nested Document Array Integer Geo-spatial Coordinates
  • 9. 9 Installare MongoDB $ curl -O https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-3.4.1.tgz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 60.9M 100 60.9M 0 0 2730k 0 0:00:22 0:00:22 --:--:-- 1589k $ tar xzvf mongodb-osx-x86_64-3.2.6.tgz x mongodb-osx-x86_64-3.2.6/README x mongodb-osx-x86_64-3.2.6/THIRD-PARTY-NOTICES x mongodb-osx-x86_64-3.2.6/MPL-2 x mongodb-osx-x86_64-3.2.6/GNU-AGPL-3.0 x mongodb-osx-x86_64-3.2.6/bin/mongodump x mongodb-osx-x86_64-3.2.6/bin/mongorestore x mongodb-osx-x86_64-3.2.6/bin/mongoexport x mongodb-osx-x86_64-3.2.6/bin/mongoimport x mongodb-osx-x86_64-3.2.6/bin/mongostat x mongodb-osx-x86_64-3.2.6/bin/mongotop x mongodb-osx-x86_64-3.2.6/bin/bsondump x mongodb-osx-x86_64-3.2.6/bin/mongofiles x mongodb-osx-x86_64-3.2.6/bin/mongooplog x mongodb-osx-x86_64-3.2.6/bin/mongoperf x mongodb-osx-x86_64-3.2.6/bin/mongosniff x mongodb-osx-x86_64-3.2.6/bin/mongod x mongodb-osx-x86_64-3.2.6/bin/mongos x mongodb-osx-x86_64-3.2.6/bin/mongo $ ln -s mongodb-osx-x86_64-3.2.6 mongodb
  • 10. 10 Eseguire mongod JD10Gen:mongodb mbrignoli$ ./bin/mongod --dbpath /data/b2b 2016-05-23T19:21:07.767+0100 I CONTROL [initandlisten] MongoDB starting : pid=49209 port=27017 dbpath=/data/b2b 64- bit host=JD10Gen.local 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] db version v3.4.1 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] git version: 05552b562c7a0b3143a729aaa0838e558dc49b25 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] allocator: system 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] modules: none 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] build environment: 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] distarch: x86_64 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] target_arch: x86_64 2016-05-23T19:21:07.768+0100 I CONTROL [initandlisten] options: { storage: { dbPath: "/data/b2b" } } 2016-05-23T19:21:07.769+0100 I - [initandlisten] Detected data files in /data/b2b created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'. 2016-05-23T19:21:07.769+0100 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=4G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true ,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB) ,statistics_log=(wait=0), 2016-05-23T19:21:08.837+0100 I CONTROL [initandlisten] 2016-05-23T19:21:08.838+0100 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000 2016-05-23T19:21:08.840+0100 I NETWORK [HostnameCanonicalizationWorker] Starting hostname canonicalization worker 2016-05-23T19:21:08.840+0100 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory '/data/b2b/diagnostic.data' 2016-05-23T19:21:08.841+0100 I NETWORK [initandlisten] waiting for connections on port 27017 2016-05-23T19:21:09.148+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:59213 #1 (1 connection now open)
  • 11. 11 Connettersi Via Shell $ ./bin/mongo MongoDB shell version: 3.4.1 connecting to: test Server has startup warnings: 2016-05-17T11:46:03.516+0100 I CONTROL [initandlisten] 2016-05-17T11:46:03.516+0100 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000 >
  • 12. 12 Inserire il Vostro Primo Record > show databases local 0.000GB > use test switched to db test > show databases local 0.000GB > db.demo.insert( { "key" : "value" } ) WriteResult({ "nInserted" : 1 }) > show databases local 0.000GB test 0.000GB > show collections demo > db.demo.findOne() { "_id" : ObjectId("573af7085ee4be80385332a6"), "key" : "value" } >
  • 15. 15 Una Semplice Applicazione di Blog • Creiamo una applicazione di blogging con questi dati: – Articles – Users – Comments
  • 16. 16 Un Tipico Diagramma Entità - Relazioni
  • 17. 17 In MongoDB possiamo farlo in modo organico > use blog switched to db blog > db.users.insert( { "username" : ”mbrignoli", "password" : "top secret", "lang" : ”IT" } ) WriteResult({ "nInserted" : 1 }) > db.users.findOne() { "_id" : ObjectId("573afff65ee4be80385332a7"), "username" : ”mbrignoli", "password" : "top secret", "lang" : ”IT" }
  • 18. 18 Come lo facciamo in un programma? ''' Created on 17 May 2016 @author: mbrignoli ''' import pymongo # # client defaults to localhost and port 27017. eg MongoClient('localhost', 27017) client = pymongo.MongoClient() blogDatabase = client[ "blog" ] usersCollection = blogDatabase[ "users" ] usersCollection.insert_one( { "username" : ”mbrignoli", "password" : "top secret", "lang" : “IT" }) user = usersCollection.find_one() print( user )
  • 19. 19 Passiamo agli Articles … articlesCollection = blogDatabase[ "articles" ] author = ”mbrignoli" article = { "title" : ”Questo è il mio primo post", "body" : ”Questo è il contenuto del mio post, posso aggiungere un sacco di testo qua.", "author" : author, "tags" : [ ”massimo", "general", ”Italia", "admin" ] } # # Lets check if our author exists # if usersCollection.find_one( { "username" : author }) : articlesCollection.insert_one( article ) else: raise ValueError( "Author %s does not exist" % author )
  • 20. 20 Creiamo un nuovo tipo di articolo # # Lets add a new type of article with a posting date and a section # author = ”mbrignoli" title = ”Questo è un post su MongoDB" newPost = { "title" : title, "body" : ”MongoDB è il database NoSQL più popolare del mondo. E’ un database a documenti.", "author" : author, "tags" : [ ”massimo", "mongodb", ”Italia" ], "section" : "technology", "postDate" : datetime.datetime.now(), } # # Lets check if our author exists # if usersCollection.find_one( { "username" : author }) : articlesCollection.insert_one( newPost )
  • 21. 21 Facciamo un po’di articoli import pymongo import string import datetime import random def randomString( size, letters = string.letters ): return "".join( [random.choice( letters ) for _ in xrange( size )] ) client = pymongo.MongoClient() def makeArticle( count, author, timestamp ): return { "_id" : count, "title" : randomString( 20 ), "body" : randomString( 80 ), "author" : author, "postdate" : timestamp } def makeUser( username ): return { "username" : username, "password" : randomString( 10 ) , "karma" : random.randint( 0, 500 ), "lang" : "EN" }
  • 22. 22 Facciamo un po’di articoli blogDatabase = client[ "blog" ] usersCollection = blogDatabase[ "users" ] articlesCollection = blogDatabase[ "articles" ] bulkUsers = usersCollection.initialize_ordered_bulk_op() bulkArticles = articlesCollection.initialize_ordered_bulk_op() ts = datetime.datetime.now() for i in range( 1000000 ) : #username = randomString( 10, string.ascii_uppercase ) + "_" + str( i ) username = "USER_" + str( i ) bulkUsers.insert( makeUser( username ) ) ts = ts + datetime.timedelta( seconds = 1 ) bulkArticles.insert( makeArticle( i, username, ts )) if ( i % 500 == 0 ) : bulkUsers.execute() bulkArticles.execute() bulkUsers = usersCollection.initialize_ordered_bulk_op() bulkArticles = articlesCollection.initialize_ordered_bulk_op() bulkUsers.execute() bulkArticles.execute()
  • 23. 23 Trovare un Utente > db.users.findOne() { "_id" : ObjectId("5742da5bb26a88bc00e941ac"), "username" : USER_1, "lang" : "EN", "password" : "vTlILbGWLt", "karma" : 448 } > db.users.find( { "username" : ”USER_45" } ).pretty() { "_id" : ObjectId("5742da5bb26a88bc00e94206"), "username" : ”USER_45", "lang" : "EN", "password" : "GmRLnCeKVp", "karma" : 284 }
  • 24. 24 Trovare gli Utenti con un alto Karma > db.users.find( { "karma" : { $gte : 450 }} ).pretty() { "_id" : ObjectId("5742da5bb26a88bc00e941ae"), "username" : "USER_1", "lang" : "EN", "password" : "bCSKSKvUeb", "karma" : 487 } { "_id" : ObjectId("5742da5bb26a88bc00e941e4"), "username" : »USER_28", "lang" : "EN", "password" : "HAWpiATCBN", "karma" : 473 } { …
  • 25. 25 Usare la Projection > db.users.find( { "karma" : { "$gte" : 450 }}, { "_id" : 0, "username" : 1 , "karma" : 1 }) { "username" : "USER_1", "karma" : 461 } { "username" : "USER_3", "karma" : 494 } { "username" : "USER_20", "karma" : 464 } { "username" : "USER_34", "karma" : 475 } { "username" : "USER_46", "karma" : 462 } { "username" : "USER_47", "karma" : 486 } { "username" : "USER_48", "karma" : 488 } { "username" : "USER_49", "karma" : 452 } { "username" : "USER_61", "karma" : 483 } { "username" : "USER_73", "karma" : 452 } { "username" : "USER_80", "karma" : 494 } { "username" : "USER_87", "karma" : 497 } …
  • 26. 26 Aggiornare un Articolo per Aggiungere Commenti > db.articles.find( { "_id" : 18 } ).pretty() { "_id" : 18, "body" : "nTzOofOcnHKkJxpjKAyqTTnKZMFzzkWFeXtBRuEKsctuGBgWIrEBrYdvFIVHJWaXLUTVUXblOZZgUq Wu", "postdate" : ISODate("2016-05-23T12:02:46.830Z"), "author" : “USER_18", "title" : "CPMaqHtAdRwLXhlUvsej" } > db.articles.update( { _id : 18 }, { $set : { comments : [] }} ) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  • 27. 27 Aggiornare un Articolo per Aggiungere Commenti > db.articles.find( { _id :18 } ).pretty() { "_id" : 18, "body" : "KmwFSIMQGcIsRNTDBFPuclwcVJkoMcrIPwTiSZDYyatoKzeQiKvJkiVSrndXqrALVIYZxGpaMjucgX UV", "postdate" : ISODate("2016-05-23T16:04:39.497Z"), "author" : "USER_18", "title" : "wTLreIEyPfovEkBhJZZe", "comments" : [ ] } >
  • 28. 28 Aggiornare un Articolo per Aggiungere Commenti > db.articles.update( { _id : 18 }, { $push : { comments : { username : ”max", comment : "hey first post" }}} ) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.articles.find( { _id :18 } ).pretty() { "_id" : 18, "body" : "KmwFSIMQGcIsRNTDBFPuclwcVJkoMcrIPwTiSZDYyatoKzeQiKvJkiVSrndXqrALVIYZxGpaMjucgXUV", "postdate" : ISODate("2016-05-23T16:04:39.497Z"), "author" : "USER_18", "title" : "wTLreIEyPfovEkBhJZZe", "comments" : [ { "username" : ”max", "comment" : "hey first post" } ] } >
  • 29. 29 Cancellare un articolo > db.articles.remove( { "_id" : 25 } ) WriteResult({ "nRemoved" : 1 }) > db.articles.remove( { "_id" : 25 } ) WriteResult({ "nRemoved" : 0 }) > db.articles.remove( { "_id" : { $lte : 5 }} ) WriteResult({ "nRemoved" : 6 }) • Le cancellazioni lasciare degli spazi vuoti • Gli spazi vuoti vengono riutilizzati
  • 30. 30 Riguardiamo gli utenti e gli articoli > db.users.findOne() { "_id" : ObjectId("57431c07b26a88bf060e10cb"), "username" : "USER_0", "lang" : "EN", "password" : "kGIxPxqKGJ", "karma" : 266 } > db.articles.findOne() { "_id" : 0, "body" : "hvJLnrrfZQurmtjPfUWbMhaQWbNjXLzjpuGLZjsxHXbUycmJVZTeOZesTnZtojThrebRcUoiYwivjpwG" , "postdate" : ISODate("2016-05-23T16:04:39.246Z"), "author" : "USER_0", "title" : "gpNIoPxpfTAxWjzAVoTJ" } >
  • 31. 31 Explain: Trova un utente > db.users.find( { "username" : "USER_99" } ).explain() { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "blog.users", "indexFilterSet" : false, "parsedQuery" : { "username" : { "$eq" : "USER_99" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "username" : { "$eq" : "USER_99" } }, "direction" : "forward" }, }, }
  • 32. 32 Explain: Trova un Utente – execution stats > db.users.find( { "username" : "USER_99" } ).explain( "executionStats" ).executionStats { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 412, "totalKeysExamined" : 0, "totalDocsExamined" : 1000000, "executionStages" : { "stage" : "COLLSCAN", "filter" : { "username" : { "$eq" : "USER_99" } }, "nReturned" : 1, "executionTimeMillisEstimate" : 302, "works" : 1000002, "advanced" : 1, "needTime" : 1000000, "needYield" : 0, "saveState" : 7823, "restoreState" : 7823, "isEOF" : 1, "invalidates" : 0, "direction" : "forward", "docsExamined" : 1000000 } }
  • 33. 33 Abbiamo Bisogno di un Indice > db.users.createIndex( { username : 1 } ) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } >
  • 34. 34 Overview degli Indici • Parametri – Background : Crea un indice in background senza lockare il db – Unique : Tutte le chiavi nella collection devono essere uniche. – Name : Da un nome all’indice, altrimenti il nome sarà generato automaticamente • Cancellare un indice – db.users.dropIndex({ “username” : 1 }) • Mostrare tutti gli indici – db.users.getIndexes()
  • 35. 35 Passaggi nell’esecuzione del Query Plan • COLLSCAN : full scan di una collection • IXSCAN : Scansione di un indice • FETCH : per leggere i documenti • SHARD_MERGE : Per unire i risultati dagli shard
  • 36. 36 Aggiungere un Indice > db.users.find( {"username" : "USER_999999”} ).explain("executionStats”).executionStats { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 0, "totalKeysExamined" : 1, "totalDocsExamined" : 1, …
  • 37. 37 Execution stage "executionStages" : { "stage" : "FETCH", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "docsExamined" : 1,, "inputStage" : { "stage" : "IXSCAN", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "keyPattern" : { "username" : 1 }, "indexName" : "username_1", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "username" : [ "["USER_999999", "USER_999999"]" ] }, "keysExamined" : 1, "seenInvalidated" : 0 } } }
  • 38. 38 Cosa Abbiamo Imparato • Come creare un database e una collection • Come inserire contenuto in una collection • Come interrogare una collection • Come aggiornare un documento • Come cancellare un documento • Come controllare l’efficienza di una query • Come aggiungere un indice • Come controllare che un indice sia usato durante una query
  • 39. 39 Prossimo Webinar : Introduzione ai Replica Sets • Come assicurare che I vostri dati sia durabili • Come recuperare da failure automaticamente • Come scrivere codice sicuro lato clienti Martedì, 20 Giugno 2017, 11:00 CET.
  • 40. Q&A

Editor's Notes

  • #3: Who I am, how long have I been at MongoDB.
  • #13: This is javascript. Lazy evaluation. Databases and collections spring to life as needed.
  • #14: 12 byte value.