SlideShare una empresa de Scribd logo
1 de 43
#MongoDB 
Transitioning from SQL to 
MongoDB 
Buzz Moschetti 
buzz.moschetti@mongodb.com 
Enterprise Architect, MongoDB
Before We Begin 
• This webinar is being recorded 
• Use The Chat Window for 
• Technical assistance 
• Q&A 
• MongoDB Team will answer quick 
questions in realtime 
• “Common” questions will be reviewed at 
the end of the webinar
Who is your Presenter? 
• Yes, I use “Buzz” on my business cards 
• Former Investment Bank Chief Architect at 
JPMorganChase and Bear Stearns before that 
• Over 27 years of designing and building systems 
• Big and small 
• Super-specialized to broadly useful in any vertical 
• “Traditional” to completely disruptive 
• Advocate of language leverage and strong factoring 
• Still programming – using emacs, of course
What Are Your Developers Doing All 
Day? 
Adding and testing business features 
OR 
“Integrating with other components, tools, and 
systems” 
• Database(s) 
• ETL and other data transfer operations 
• Messaging 
• Services (web & other) 
• Other open source frameworks incl. 
ORMs
Why Can’t We Just Save and Fetch 
Data? 
Because the way we think about data at the 
business use case level… 
…is different than the way it is implemented at 
the application/code level… 
…which traditionally is VERY different than the 
way it is implemented at the database level
This Problem Isn’t New… 
…but for the past 40 years, innovation at the business & application layers 
has outpaced innovation at the database layer 
1974 2014 
Business 
Data Goals 
Capture my company’s 
transactions daily at 
5:30PM EST, add them up 
on a nightly basis, and print 
a big stack of paper 
Capture my company’s global transactions in realtime 
plus everything that is happening in the world 
(customers, competitors, business/regulatory/weather), 
producing any number of computed results, and passing 
this all in realtime to predictive analytics with model 
feedback; results in realtime to 10000s of mobile 
devices, multiple GUIs, and b2b and b2c channels 
Release 
Schedule 
Semi-Annually Yesterday 
Application 
/Code 
COBOL, Fortran, Algol, 
PL/1, assembler, 
proprietary tools 
C, C++, VB, C#, Java, javascript, groovy, ruby, perl 
python, Obj-C, SmallTalk, Clojure, ActionScript, Flex, 
DSLs, spring, AOP, CORBA, ORM, third party software 
ecosystem, the whole open source movement, … and 
COBOL and Fortran 
Database I/VSAM, early RDBMS Mature RDBMS, legacy I/VSAM 
Column & key/value stores, and…mongoDB
Exactly How Does MongoDB Change 
Things? 
• MongoDB is designed from the ground up to 
address rich structure (maps of maps of lists 
of…), not rectangles 
• Standard RDBMS interfaces (i.e. JDBC) do not exploit features 
of contemporary languages 
• Rapid Application Development (RAD) and scripting in 
Javascript, Python, Perl, Ruby, and Scala is impedance-matched 
to mongoDB 
• In MongoDB, the data is the schema 
• Shapes of data go in the same way they come 
out
Rectangles are 1974. Maps and Lists are 
2014 
{ customer_id : 1, 
first_name : "Mark", 
last_name : "Smith", 
city : "San Francisco", 
phones: [ { 
type : “work”, 
number: “1-800-555-1212” 
}, 
{ type : “home”, 
number: “1-800-555-1313”, 
DNC: true 
}, 
{ type : “home”, 
number: “1-800-555-1414”, 
DNC: true 
} 
] 
}
An Actual Code Example (Finally!) 
Let’s compare and contrast RDBMS/SQL to MongoDB 
development using Java over the course of a few weeks. 
Some ground rules: 
1. Observe rules of Software Engineering 101: Assume separation of application, 
Data Access Layer, and persistor implementation 
2. Data Access Layer must be able to 
a. Expose simple, functional, data-only interfaces to the application 
• No ORM, frameworks, compile-time bindings, special tools 
b. Exploit high performance features of persistor 
3. Focus on core data handling code and avoid distractions that require the same 
amount of work in both technologies 
a. No exception or error handling 
b. Leave out DB connection and other setup resources 
4. Day counts are a proxy for progress, not actual time to complete indicated task
The Task: Saving and Fetching Contact 
data 
Map m = new HashMap(); 
m.put(“name”, “buzz”); 
m.put(“id”, “K1”); 
Start with this simple, 
flat shape in the Data 
Access Layer: 
save(Map m) 
And assume we 
save it in this way: 
Map m = fetch(String id) 
And assume we 
fetch one by primary 
key in this way: 
Brace yourself…..
Day 1: Initial efforts for both technologies 
SQL 
DDL: create table contact ( … ) 
init() 
{ 
contactInsertStmt = connection.prepareStatement 
(“insert into contact ( id, name ) values ( ?,? )”); 
fetchStmt = connection.prepareStatement 
(“select id, name from contact where id = ?”); 
} 
save(Map m) 
{ 
contactInsertStmt.setString(1, m.get(“id”)); 
contactInsertStmt.setString(2, m.get(“name”)); 
contactInsertStmt.execute(); 
} 
Map fetch(String id) 
{ 
Map m = null; 
fetchStmt.setString(1, id); 
rs = fetchStmt.execute(); 
if(rs.next()) { 
m = new HashMap(); 
m.put(“id”, rs.getString(1)); 
m.put(“name”, rs.getString(2)); 
} 
return m; 
} 
MongoDB 
DDL: none 
save(Map m) 
{ 
collection.insert(m); 
} 
Map fetch(String id) 
{ 
Map m = null; 
DBObject dbo = new BasicDBObject(); 
dbo.put(“id”, id); 
c = collection.find(dbo); 
if(c.hasNext()) } 
m = (Map) c.next(); 
} 
return m; 
}
Day 2: Add simple fields 
m.put(“name”, “buzz”); 
m.put(“id”, “K1”); 
m.put(“title”, “Mr.”); 
m.put(“hireDate”, new Date(2011, 11, 1)); 
• Capturing title and hireDate is part of adding a new 
business feature 
• It was pretty easy to add two fields to the structure 
• …but now we have to change our persistence code 
Brace yourself (again) …..
SQL Day 2 (changes in bold) 
DDL: alter table contact add title varchar(8); 
alter table contact add hireDate date; 
init() 
{ 
contactInsertStmt = connection.prepareStatement 
(“insert into contact ( id, name, title, hiredate ) values 
( ?,?,?,? )”); 
fetchStmt = connection.prepareStatement 
(“select id, name, title, hiredate from contact where id = 
?”); 
} 
save(Map m) 
{ 
contactInsertStmt.setString(1, m.get(“id”)); 
contactInsertStmt.setString(2, m.get(“name”)); 
contactInsertStmt.setString(3, m.get(“title”)); 
contactInsertStmt.setDate(4, m.get(“hireDate”)); 
contactInsertStmt.execute(); 
} 
Map fetch(String id) 
{ 
Map m = null; 
fetchStmt.setString(1, id); 
rs = fetchStmt.execute(); 
if(rs.next()) { 
m = new HashMap(); 
m.put(“id”, rs.getString(1)); 
m.put(“name”, rs.getString(2)); 
m.put(“title”, rs.getString(3)); 
m.put(“hireDate”, rs.getDate(4)); 
} 
return m; 
} 
Consequences: 
1. Code release schedule linked 
to database upgrade (new 
code cannot run on old 
schema) 
2. Issues with case sensitivity 
starting to creep in (many 
RDBMS are case insensitive 
for column names, but code is 
case sensitive) 
3. Changes require careful mods 
in 4 places 
4. Beginning of technical debt
MongoDB Day 2 
save(Map m) 
{ 
collection.insert(m); 
} 
Map fetch(String id) 
{ 
Map m = null; 
DBObject dbo = new BasicDBObject(); 
dbo.put(“id”, id); 
c = collection.find(dbo); 
if(c.hasNext()) } 
m = (Map) c.next(); 
} 
return m; 
} 
Advantages: 
1. Zero time and money spent on 
overhead code 
2. Code and database not physically 
linked 
3. New material with more fields can 
be added into existing collections; 
backfill is optional 
4. Names of fields in database 
precisely match key names in 
code layer and directly match on 
name, not indirectly via positional 
offset 
5. No technical debt is created 
✔ NO 
CHANGE
Day 3: Add list of phone numbers 
m.put(“name”, “buzz”); 
m.put(“id”, “K1”); 
m.put(“title”, “Mr.”); 
m.put(“hireDate”, new Date(2011, 11, 
1)); 
n1.put(“type”, “work”); 
n1.put(“number”, “1-800-555-1212”)); 
list.add(n1); 
n2.put(“type”, “home”)); 
n2.put(“number”, “1-866-444-3131”)); 
list.add(n2); 
m.put(“phones”, list); 
• It was still pretty easy to add this data to the structure 
• .. but meanwhile, in the persistence code … 
REALLY brace yourself…
SQL Day 3 changes: Option 1: Assume 
just 1 work and 1 home phone number 
DDL: alter table contact add work_phone varchar(16); 
alter table contact add home_phone varchar(16); 
init() 
{ 
contactInsertStmt = connection.prepareStatement 
(“insert into contact ( id, name, title, hiredate, 
work_phone, home_phone ) values ( ?,?,?,?,?,? )”); 
fetchStmt = connection.prepareStatement 
(“select id, name, title, hiredate, work_phone, 
home_phone from contact where id = ?”); 
} 
save(Map m) 
{ 
contactInsertStmt.setString(1, m.get(“id”)); 
contactInsertStmt.setString(2, m.get(“name”)); 
contactInsertStmt.setString(3, m.get(“title”)); 
contactInsertStmt.setDate(4, m.get(“hireDate”)); 
for(Map onePhone : m.get(“phones”)) { 
String t = onePhone.get(“type”); 
String n = onePhone.get(“number”); 
if(t.equals(“work”)) { 
contactInsertStmt.setString(5, n); 
} else if(t.equals(“home”)) { 
contactInsertStmt.setString(6, n); 
} 
} 
contactInsertStmt.execute(); 
} 
Map fetch(String id) 
{ 
Map m = null; 
fetchStmt.setString(1, id); 
rs = fetchStmt.execute(); 
if(rs.next()) { 
m = new HashMap(); 
m.put(“id”, rs.getString(1)); 
m.put(“name”, rs.getString(2)); 
m.put(“title”, rs.getString(3)); 
m.put(“hireDate”, rs.getDate(4)); 
Map onePhone; 
onePhone = new HashMap(); 
onePhone.put(“type”, “work”); 
onePhone.put(“number”, rs.getString(5)); 
list.add(onePhone); 
onePhone = new HashMap(); 
onePhone.put(“type”, “home”); 
onePhone.put(“number”, rs.getString(6)); 
list.add(onePhone); 
m.put(“phones”, list); 
} 
This is just plain bad….
SQL Day 3 changes: Option 2: 
Proper approach with multiple phone 
numbers DDL: create table phones ( … ) 
init() 
{ 
contactInsertStmt = connection.prepareStatement 
(“insert into contact ( id, name, title, hiredate ) 
values ( ?,?,?,? )”); 
c2stmt = connection.prepareStatement(“insert into 
phones (id, type, number) values (?, ?, ?)”; 
fetchStmt = connection.prepareStatement 
(“select id, name, title, hiredate, type, number from 
contact, phones where phones.id = contact.id and 
contact.id = ?”); 
} 
save(Map m) 
{ 
startTrans(); 
contactInsertStmt.setString(1, m.get(“id”)); 
contactInsertStmt.setString(2, m.get(“name”)); 
contactInsertStmt.setString(3, m.get(“title”)); 
contactInsertStmt.setDate(4, m.get(“hireDate”)); 
for(Map onePhone : m.get(“phones”)) { 
c2stmt.setString(1, m.get(“id”)); 
c2stmt.setString(2, onePhone.get(“type”)); 
c2stmt.setString(3, onePhone.get(“number”)); 
c2stmt.execute(); 
} 
contactInsertStmt.execute(); 
endTrans(); 
} 
Map fetch(String id) 
{ 
Map m = null; 
fetchStmt.setString(1, id); 
rs = fetchStmt.execute(); 
int i = 0; 
List list = new ArrayList(); 
while (rs.next()) { 
if(i == 0) { 
m = new HashMap(); 
m.put(“id”, rs.getString(1)); 
m.put(“name”, rs.getString(2)); 
m.put(“title”, rs.getString(3)); 
m.put(“hireDate”, rs.getDate(4)); 
m.put(“phones”, list); 
} 
Map onePhone = new HashMap(); 
onePhone.put(“type”, rs.getString(5)); 
onePhone.put(“number”, rs.getString(6)); 
list.add(onePhone); 
i++; 
} 
return m; 
} 
This took time and money
SQL Day 5: Zombies! (zero or more between entities) 
init() 
{ 
contactInsertStmt = connection.prepareStatement 
(“insert into contact ( id, name, title, hiredate ) 
values ( ?,?,?,? )”); 
c2stmt = connection.prepareStatement(“insert into 
phones (id, type, number) values (?, ?, ?)”; 
fetchStmt = connection.prepareStatement 
(“select A.id, A.name, A.title, A.hiredate, B.type, 
B.number from contact A left outer join phones B on 
(A.id = B. id) where A.id = ?”); 
} 
Whoops! And it’s also wrong! 
We did not design the query accounting 
for contacts that have no phone number. 
Thus, we have to change the join to an 
outer join. 
But this ALSO means we have to change 
the unwind logic 
This took more time and 
money! 
while (rs.next()) { 
if(i == 0) { 
// … 
} 
String s = rs.getString(5); 
if(s != null) { 
Map onePhone = new HashMap(); 
onePhone.put(“type”, s); 
onePhone.put(“number”, rs.getString(6)); 
list.add(onePhone); 
} 
} 
…but at least we have a DAL… 
right?
MongoDB Day 3 
Advantages: 
1. Zero time and money spent on 
overhead code 
2. No need to fear fields that are 
“naturally occurring” lists 
containing data specific to the 
parent structure and thus do not 
benefit from normalization and 
referential integrity 
3. Safe from zombies and other 
undead distractions from productivity 
save(Map m) 
{ 
collection.insert(m); 
} 
Map fetch(String id) 
{ 
Map m = null; 
DBObject dbo = new BasicDBObject(); 
dbo.put(“id”, id); 
c = collection.find(dbo); 
if(c.hasNext()) } 
m = (Map) c.next(); 
} 
return m; 
} 
✔ NO 
CHANGE
By Day 14, our structure looks like this: 
n4.put(“geo”, “US-EAST”); 
n4.put(“startupApps”, new String[] { “app1”, “app2”, “app3” } ); 
list2.add(n4); 
n4.put(“geo”, “EMEA”); 
n4.put(“startupApps”, new String[] { “app6” } ); 
n4.put(“useLocalNumberFormats”, false): 
list2.add(n4); 
m.put(“preferences”, list2) 
n6.put(“optOut”, true); 
n6.put(“assertDate”, someDate); 
seclist.add(n6); 
m.put(“attestations”, seclist) 
m.put(“security”, mapOfDataCreatedByExternalSource); 
• It was still pretty easy to add this data to the structure 
• Want to guess what the SQL persistence code looks like? 
• How about the MongoDB persistence code?
SQL Day 14 
Error: Could not fit all the code into this space. 
…actually, I didn’t want to spend 2 hours putting the code together.. 
But very likely, among other things: 
• n4.put(“startupApps”,new String[]{“app1”,“app2”,“app3”}); 
was implemented as a single semi-colon delimited string 
• m.put(“security”, anotherMapOfData); 
was implemented by flattening it out and storing a subset of fields
MongoDB Day 14 – and every other day 
Advantages: 
1. Zero time and money spent on 
overhead code 
2. Persistence is so easy and flexible 
and backward compatible that the 
persistor does not upward-influence 
the shapes we want to 
persist i.e. the tail does not wag 
the dog 
save(Map m) 
{ 
collection.insert(m); 
} 
Map fetch(String id) 
{ 
Map m = null; 
DBObject dbo = new BasicDBObject(); 
dbo.put(“id”, id); 
c = collection.find(dbo); 
if(c.hasNext()) } 
m = (Map) c.next(); 
} 
return m; 
} 
✔ NO 
CHANGE
But what if we must do a join? 
Both RDBMS and MongoDB will have a PhoneTransactions 
table/collection 
{ customer_id : 1, 
first_name : "Mark", 
last_name : "Smith", 
city : "San Francisco", 
phones: [ { 
type : “work”, 
number: “1-800-555-1212” 
}, 
{ type : “home”, 
number: “1-800-555-1313”, 
DNC: true 
}, 
{ type : “home”, 
number: “1-800-555-1414”, 
DNC: true 
} 
] 
} 
{ number: “1-800-555-1212”, 
target: “1-999-238-3423”, 
duration: 20 
} 
{ number: “1-800-555-1212”, 
target: “1-444-785-6611”, 
duration: 243 
} 
{ number: “1-800-555-1414”, 
target: “1-645-331-4345”, 
duration: 132 
} 
{ number: “1-800-555-1414”, 
target: “1-990-875-2134”, 
duration: 71 
} 
PhoneTransactions
SQL Join Attempt #1 
select A.id, A.lname, B.type, B.number, C.target, C.duration 
from contact A, phones B, phonestx C 
Where A.id = B.id and B.number = C.number 
id | lname | type | number | target | duration 
-----+--------------+------+----------------+----------------+---------- 
g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7070 | 23 
g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7071 | 7 
g9 | Moschetti | work | 1-800-989-2231 | 1-987-707-7072 | 9 
g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7071 | 7 
g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7070 | 23 
g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7071 | 7 
g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7070 | 23 
g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7072 | 9 
g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7072 | 9 
g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7072 | 9 
How to turn this into a list of names – 
each with a list of numbers, each of those with a list of target 
numbers?
SQL Unwind Attempt #1 
Map idmap = new HashMap(); 
ResultSet rs = fetchStmt.execute(); 
while (rs.next()) { 
String id = rs.getString(“id"); 
String nmbr = rs.getString("number"); 
List tnum; 
Map snum; 
if((snum = (List) idmap.get(id)) == null) { 
snum = new HashMap(); 
idmap.put(did, snum); 
} 
if((tnum = snum.get(nmbr)) == null) { 
tnum = new ArrayList(); 
snum.put(number, tnum); 
} 
Map info = new HashMap(); 
info.put("target", rs.getString("target")); 
info.put("duration", rs.getInteger("duration")); 
tnum.add(info); 
} 
// idmap[“g9”][“1-900-555-1212”] = ({target:1-222-707-7070,duration:23…)
SQL Join Attempt #2 
select A.id, A.lname, B.type, B.number, C.target, C.duration 
Fromcontact A, phones B, phonestx C 
Where A.id = B.id and B.number = C.number order by A.id, B.number 
id | lname | type | number | target | duration 
-----+--------------+------+----------------+----------------+---------- 
g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7072 | 9 
g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7070 | 23 
g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7071 | 7 
g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7072 | 9 
g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7070 | 23 
g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7071 | 7 
g9 | Moschetti | work | 1-800-989-2231 | 1-987-707-7072 | 9 
g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7071 | 7 
g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7072 | 9 
g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7070 | 23 
“Early bail out” from cursor is now possible – 
but logic to construct list of source and target numbers is similar
SQL is about Disassembly 
String s = “select A, B, C, D, 
E, F from T1,T2,T3 where T1.col 
= T2.col and T2.col2 = T3.col2 
and X = Y and X2 != Y2 and G > 
10 and G < 100 and TO_DATE(‘ …”; 
ResultSet rs = execute(s); 
while(ResultSet.next()) { 
if(new column1 value from T1) { 
set up new Object; 
} 
if(new column2 value from T2) { 
set up new Object2 
} 
if(new column3 value from T3) { 
set up new Object3 
} 
populate maps, lists and scalars 
} 
Design a Big Query 
including business logic 
to grab all the data up 
front 
Throw it at the engine 
Disassemble Big 
Rectangle into usable 
objects with logic implicit 
in change in column 
values
MongoDB is about Assembly 
Cursor c = coll1.find({“X”:”Y”}); 
while(c.hasNext()) { 
populate maps, lists and scalars; 
Cursor c2 = coll2.find(logic+key from c); 
while(c2.hasNext()) { 
populate maps, lists and scalars; 
Cursor c3 = coll3.find(logic+key from c2); 
while(c3.hasNext()) { 
populate maps, lists and scalars; 
} 
} 
Assemble usable 
objects incrementally 
with explicit logic
MongoDB ”Join” 
Map idmap = new HashMap(); 
DBCursor c = contacts.find(); 
while(c.hasNext()) { 
DBObject item = c.next(); 
String id = item.get(“id”); 
Map nummap = new HashMap(); 
for(Map phone : (List)item.get(”phones”)) { 
String pnum = phone.get(“number”); 
DBObject q = new BasicDBObject(“number”, pnum); 
DBCursor c2 = phonestx.find(q); 
List txs = new ArrayList(); 
while(c2.hasNext()) { 
txs.add((Map)c2.next()); 
} 
nummap.put(pnum, txs); 
} 
idmap.put(id, nummap); 
} 
// idmap[“g9”][“1-900-555-1212”] = ({target:1-222-707-7070,duration:23…)
But what about “real” queries? 
• MongoDB query language is a physical map-of-map 
based structure, not a String 
• Operators (e.g. AND, OR, GT, EQ, etc.) and arguments are 
keys and values in a cascade of Maps 
• No grammar to parse, no templates to fill in, no whitespace, 
no escaping quotes, no parentheses, no punctuation 
• Same paradigm to manipulate data is used to 
manipulate query expressions 
• …which is also, by the way, the same paradigm 
for working with MongoDB metadata and 
explain()
MongoDB Query Examples 
Find all contacts with at least one work phone 
SQL CLI select * from contact A, phones B where 
A.did = B.did and B.type = 'work’; 
MongoDB CLI db.contact.find({"phones.type”:”work”}); 
SQL in Java String s = “select * from contact A, phones B 
where A.did = B.did and B.type = 'work’”; 
ResultSet rs = execute(s); 
MongoDB via 
Java driver 
DBObject expr = new BasicDBObject(); 
expr.put(“phones.type”, “work”); 
Cursor c = contact.find(expr);
MongoDB Query Examples 
Find all contacts with at least one work phone or 
hired after 2014-02-02 
SQL select A.did, A.lname, A.hiredate, B.type, 
B.number from contact A left outer join phones B 
on (B.did = A.did) where b.type = 'work' or 
A.hiredate > '2014-02-02'::date 
MongoDB CLI db.contacts.find({"$or”: [ 
{"phones.number":"1-900-555- 
1212”}, {"hireda 
te": {”$gt": new ISODate("2014-02-02")}} 
]});
MongoDB Query Examples 
Find all contacts with at least one work phone or 
hired after 2014-02-02 
MongoDB via 
Java driver 
List arr = new ArrayList(); 
Map phones = new HashMap(); 
phones.put(“phones.type”, “work”); 
arr.add(phones); 
Map hdate = new HashMap(); 
java.util.Date d = dateFromStr(“2014-02-02”); 
hdate.put(“hiredate”, new BasicDBObject(“$gt”,d)); 
Map m1 = new HashMap(); 
m1.put(“$or”, arr); 
contact.find(new BasicDBObject(m1));
…and before you ask… 
Yes, MongoDB query expressions 
support 
1. Sorting 
2. Cursor size limit 
3. Projection (asking for only parts of the rich 
shape to be returned) 
4. Aggregation (“GROUP BY”) functions
Day 30: RAD on MongoDB with Python 
import pymongo 
def save(data): 
coll.insert(data) 
def fetch(id): 
return coll.find_one({”id": id } ) 
myData = { 
“name”: “jane”, 
“id”: “K2”, 
# no title? No problem 
“hireDate”: datetime.date(2011, 11, 1), 
“phones”: [ 
{ "type": "work", 
"number": "1-800-555-1212" 
}, 
{ "type": "home", 
"number": "1-866-444-3131" 
} 
] 
} 
save(myData) 
print fetch(“K2”) 
expr = {"$or": [ {"phones.type": “work”}, {”hiredate": {“$gt”: datetime.date(2014,2,2)}} ]} 
for c in coll.find(expr): 
print [ k.upper() for k in sorted(c.keys()) ] 
Advantages: 
1. Far easier and faster to create 
scripts due to “fidelity-parity” of 
mongoDB map data and python 
(and perl, ruby, and javascript) 
structures 
1. Data types and structure in scripts 
are exactly the same as that read and 
written in Java and C++
Day 30: Polymorphic RAD on MongoDB with 
Python 
import pymongo 
item = fetch("K8") 
# item is: 
{ 
“name”: “bob”, 
“id”: “K8”, 
"personalData": { 
"preferedAirports": [ "LGA", "JFK" ], 
"travelTimeThreshold": { "value": 3, 
"units": “HRS”} 
} 
} 
item = fetch("K9") 
# item is: 
{ 
“name”: “steve”, 
“id”: “K9”, 
"personalData": { 
"lastAccountVisited": { 
"name": "mongoDB", 
"when": datetime.date(2013,11,4) 
}, 
"favoriteNumber": 3.14159 
} 
} 
Advantages: 
1. Scripting languages easily digest 
shapes with common fields and 
dissimilar fields 
2. Easy to create an information 
architecture where placeholder fields 
like personalData are “known” in the 
software logic to be dynamic
Day 30: (Not) RAD on top of SQL with 
Python 
init() 
{ 
contactInsertStmt = connection.prepareStatement 
(“insert into contact ( id, name, title, hiredate ) 
values ( ?,?,?,? )”); 
c2stmt = connection.prepareStatement(“insert into 
phones (id, type, number) values (?, ?, ?)”; 
fetchStmt = connection.prepareStatement 
(“select id, name, title, hiredate, type, number from 
contact, phones where phones.id = contact.id and 
contact.id = ?”); 
} 
save(Map m) 
{ 
startTrans(); 
contactInsertStmt.setString(1, m.get(“id”)); 
contactInsertStmt.setString(2, m.get(“name”)); 
contactInsertStmt.setString(3, m.get(“title”)); 
contactInsertStmt.setDate(4, m.get(“hireDate”)); 
for(Map onePhone : m.get(“phones”)) { 
c2stmt.setString(1, onePhone.get(“type”)); 
c2stmt.setString(2, onePhone.get(“number”)); 
c2stmt.execute(); 
} 
contactInsertStmt.execute(); 
endTrans(); 
} 
Consequences: 
1. All logic coded in Java interface 
layer (unwinding contact, phones, 
preferences, etc.) needs to be 
rewritten in python (unless Jython 
is used) … AND/or perl, C++, 
Scala, etc. 
2. No robust way to handle 
polymorphic data other than 
BLOBing it 
3. …and that will take real time and 
money!
The Fundamental Change with mongoDB 
RDBMS designed in era when: 
• CPU and disk was slow & 
expensive 
• Memory was VERY expensive 
• Network? What network? 
• Languages had limited means to 
dynamically reflect on their types 
• Languages had poor support for 
richly structured types 
Thus, the database had to 
• Act as combiner-coordinator of 
simpler types 
• Define a rigid schema 
• (Together with the code) optimize 
at compile-time, not run-time 
In mongoDB, the 
data is the schema!
mongoDB and the Rich Map Ecosystem 
Generic comparison of two 
records 
Map expr = new HashMap(); 
expr.put("myKey", "K1"); 
DBObject a = collection.findOne(expr); 
expr.put("myKey", "K2"); 
DBObject b = collection.findOne(expr); 
List<MapDiff.Difference> d = MapDiff.diff((Map)a, (Map)b); 
Getting default values for a thing 
on a certain date and then 
overlaying user preferences (like 
for a calculation run) 
Map expr = new HashMap(); 
expr.put("myKey", "DEFAULT"); 
expr.put("createDate", new Date(2013, 11, 1)); 
DBObject a = collection.findOne(expr); 
expr.clear(); 
expr.put("myKey", "user1"); 
DBObject b = otherCollectionPerhaps.findOne(expr); 
MapStack s = new MapStack(); 
s.push((Map)a); 
s.push((Map)b); 
Map merged = s.project(); 
Runtime reflection of Maps and Lists enables generic powerful utilities 
(MapDiff, MapStack) to be created once and used for all kinds of shapes, 
saving time and money
Lastly: A CLI with teeth 
> db.contact.find({"SeqNum": {"$gt”:10000}}).explain(); 
{ 
"cursor" : "BasicCursor", 
"n" : 200000, 
//... 
"millis" : 223 
} 
Try a query and show the 
diagnostics 
> for(v=[],i=0;i<3;i++) { 
… n = i*50000; 
… expr = {"SeqNum": {"$gt”: n}}; 
… v.push( [n, db.contact.find(expr).explain().millis)] } 
Run it 3 times with smaller and 
smaller chunks and create a 
vector of timing result pairs 
(size,time) 
> v 
[ [ 0, 225 ], [ 50000, 222 ], [ 100000, 220 ] ] 
Let’s see that vector 
> load(“jStat.js”) 
> jStat.stdev(v.map(function(p){return p[1];})) 
2.0548046676563256 
Use any other javascript you 
want inside the shell 
> for(i=0;i<3;i++) { 
… expr = {"SeqNum": {"$gt":i*1000}}; 
… db.foo.insert(db.contact.find(expr).explain()); } 
Party trick: save the explain() 
output back into a collection!
What Does All This Add Up To? 
• MongoDB easier than RDBMS/SQL for real 
problems 
• Quicker to change 
• Much better harmonized with modern languages 
+ 
• Comprehensive indexing (arbitrary non/unique 
secondaries, compound keys, geospatial, text 
search, TTL, etc….) 
• Horizontally scalable to petabytes 
• Isomorphic HA and DR 
Modern Database for Modern 
Solutions 
=
Webinar Q&A 
buzz.moschetti@mongodb.com
#MongoDB 
Thank You 
Buzz Moschetti 
buzz.moschetti@mongodb.com 
Enterprise Architect, MongoDB

Más contenido relacionado

La actualidad más candente

Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBMongoDB
 
Webinar: When to Use MongoDB
Webinar: When to Use MongoDBWebinar: When to Use MongoDB
Webinar: When to Use MongoDBMongoDB
 
MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...
MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...
MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...MongoDB
 
MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...
MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...
MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...MongoDB
 
Migrating to MongoDB: Best Practices
Migrating to MongoDB: Best PracticesMigrating to MongoDB: Best Practices
Migrating to MongoDB: Best PracticesMongoDB
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB Habilelabs
 
Agility and Scalability with MongoDB
Agility and Scalability with MongoDBAgility and Scalability with MongoDB
Agility and Scalability with MongoDBMongoDB
 
Advanced Schema Design Patterns
Advanced Schema Design PatternsAdvanced Schema Design Patterns
Advanced Schema Design PatternsMongoDB
 
Hybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsHybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsSteven Francia
 
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
 
Webinar: Schema Patterns and Your Storage Engine
Webinar: Schema Patterns and Your Storage EngineWebinar: Schema Patterns and Your Storage Engine
Webinar: Schema Patterns and Your Storage EngineMongoDB
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBJustin Smestad
 
Introduction To MongoDB
Introduction To MongoDBIntroduction To MongoDB
Introduction To MongoDBElieHannouch
 
MongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQL
MongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQLMongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQL
MongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQLMongoDB
 
High Performance Applications with MongoDB
High Performance Applications with MongoDBHigh Performance Applications with MongoDB
High Performance Applications with MongoDBMongoDB
 
MongoDB vs Mysql. A devops point of view
MongoDB vs Mysql. A devops point of viewMongoDB vs Mysql. A devops point of view
MongoDB vs Mysql. A devops point of viewPierre Baillet
 

La actualidad más candente (20)

Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Webinar: When to Use MongoDB
Webinar: When to Use MongoDBWebinar: When to Use MongoDB
Webinar: When to Use MongoDB
 
MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...
MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...
MongoDB World 2019: Raiders of the Anti-patterns: A Journey Towards Fixing Sc...
 
MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...
MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...
MongoDB World 2019: Finding the Right MongoDB Atlas Cluster Size: Does This I...
 
Migrating to MongoDB: Best Practices
Migrating to MongoDB: Best PracticesMigrating to MongoDB: Best Practices
Migrating to MongoDB: Best Practices
 
Mongo DB
Mongo DBMongo DB
Mongo DB
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB
 
Agility and Scalability with MongoDB
Agility and Scalability with MongoDBAgility and Scalability with MongoDB
Agility and Scalability with MongoDB
 
Advanced Schema Design Patterns
Advanced Schema Design PatternsAdvanced Schema Design Patterns
Advanced Schema Design Patterns
 
MongodB Internals
MongodB InternalsMongodB Internals
MongodB Internals
 
Hybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsHybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS Applications
 
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)
 
Mongo db operations_v2
Mongo db operations_v2Mongo db operations_v2
Mongo db operations_v2
 
Webinar: Schema Patterns and Your Storage Engine
Webinar: Schema Patterns and Your Storage EngineWebinar: Schema Patterns and Your Storage Engine
Webinar: Schema Patterns and Your Storage Engine
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Introduction To MongoDB
Introduction To MongoDBIntroduction To MongoDB
Introduction To MongoDB
 
MongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQL
MongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQLMongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQL
MongoDB .local London 2019: Managing Diverse User Needs with MongoDB and SQL
 
Mongo db intro.pptx
Mongo db intro.pptxMongo db intro.pptx
Mongo db intro.pptx
 
High Performance Applications with MongoDB
High Performance Applications with MongoDBHigh Performance Applications with MongoDB
High Performance Applications with MongoDB
 
MongoDB vs Mysql. A devops point of view
MongoDB vs Mysql. A devops point of viewMongoDB vs Mysql. A devops point of view
MongoDB vs Mysql. A devops point of view
 

Similar a Transitioning from SQL to MongoDB

Benefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSsBenefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSsMongoDB
 
Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...
Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...
Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...MongoDB
 
Reducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQLReducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQLMongoDB
 
Database Trends for Modern Applications: Why the Database You Choose Matters
Database Trends for Modern Applications: Why the Database You Choose Matters Database Trends for Modern Applications: Why the Database You Choose Matters
Database Trends for Modern Applications: Why the Database You Choose Matters MongoDB
 
Webinar: Transitioning from SQL to MongoDB
Webinar: Transitioning from SQL to MongoDBWebinar: Transitioning from SQL to MongoDB
Webinar: Transitioning from SQL to MongoDBMongoDB
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8tdc-globalcode
 
Go Programming Patterns
Go Programming PatternsGo Programming Patterns
Go Programming PatternsHao Chen
 
Visual studio 2008
Visual studio 2008Visual studio 2008
Visual studio 2008Luis Enrique
 
OrientDB - The 2nd generation of (multi-model) NoSQL
OrientDB - The 2nd generation of  (multi-model) NoSQLOrientDB - The 2nd generation of  (multi-model) NoSQL
OrientDB - The 2nd generation of (multi-model) NoSQLRoberto Franchini
 
Application Development & Database Choices: Postgres Support for non Relation...
Application Development & Database Choices: Postgres Support for non Relation...Application Development & Database Choices: Postgres Support for non Relation...
Application Development & Database Choices: Postgres Support for non Relation...EDB
 
Introduction to MongoDB at IGDTUW
Introduction to MongoDB at IGDTUWIntroduction to MongoDB at IGDTUW
Introduction to MongoDB at IGDTUWAnkur Raina
 
Building Services With gRPC, Docker and Go
Building Services With gRPC, Docker and GoBuilding Services With gRPC, Docker and Go
Building Services With gRPC, Docker and GoMartin Kess
 
RedisConf18 - Redis Memory Optimization
RedisConf18 - Redis Memory OptimizationRedisConf18 - Redis Memory Optimization
RedisConf18 - Redis Memory OptimizationRedis Labs
 
AI與大數據數據處理 Spark實戰(20171216)
AI與大數據數據處理 Spark實戰(20171216)AI與大數據數據處理 Spark實戰(20171216)
AI與大數據數據處理 Spark實戰(20171216)Paul Chao
 
When to Use MongoDB
When to Use MongoDB When to Use MongoDB
When to Use MongoDB MongoDB
 
State of the Art Web Mapping with Open Source
State of the Art Web Mapping with Open SourceState of the Art Web Mapping with Open Source
State of the Art Web Mapping with Open SourceOSCON Byrum
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Paulo Gandra de Sousa
 

Similar a Transitioning from SQL to MongoDB (20)

Benefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSsBenefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSs
 
Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...
Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...
Benefits of Using MongoDB Over RDBMS (At An Evening with MongoDB Minneapolis ...
 
Reducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQLReducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQL
 
Database Trends for Modern Applications: Why the Database You Choose Matters
Database Trends for Modern Applications: Why the Database You Choose Matters Database Trends for Modern Applications: Why the Database You Choose Matters
Database Trends for Modern Applications: Why the Database You Choose Matters
 
Webinar: Transitioning from SQL to MongoDB
Webinar: Transitioning from SQL to MongoDBWebinar: Transitioning from SQL to MongoDB
Webinar: Transitioning from SQL to MongoDB
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
 
Novidades do c# 7 e 8
Novidades do c# 7 e 8Novidades do c# 7 e 8
Novidades do c# 7 e 8
 
Go Programming Patterns
Go Programming PatternsGo Programming Patterns
Go Programming Patterns
 
Visual studio 2008
Visual studio 2008Visual studio 2008
Visual studio 2008
 
OrientDB - The 2nd generation of (multi-model) NoSQL
OrientDB - The 2nd generation of  (multi-model) NoSQLOrientDB - The 2nd generation of  (multi-model) NoSQL
OrientDB - The 2nd generation of (multi-model) NoSQL
 
Application Development & Database Choices: Postgres Support for non Relation...
Application Development & Database Choices: Postgres Support for non Relation...Application Development & Database Choices: Postgres Support for non Relation...
Application Development & Database Choices: Postgres Support for non Relation...
 
Introduction to MongoDB at IGDTUW
Introduction to MongoDB at IGDTUWIntroduction to MongoDB at IGDTUW
Introduction to MongoDB at IGDTUW
 
Building Services With gRPC, Docker and Go
Building Services With gRPC, Docker and GoBuilding Services With gRPC, Docker and Go
Building Services With gRPC, Docker and Go
 
RedisConf18 - Redis Memory Optimization
RedisConf18 - Redis Memory OptimizationRedisConf18 - Redis Memory Optimization
RedisConf18 - Redis Memory Optimization
 
AI與大數據數據處理 Spark實戰(20171216)
AI與大數據數據處理 Spark實戰(20171216)AI與大數據數據處理 Spark實戰(20171216)
AI與大數據數據處理 Spark實戰(20171216)
 
When to Use MongoDB
When to Use MongoDB When to Use MongoDB
When to Use MongoDB
 
State of the Art Web Mapping with Open Source
State of the Art Web Mapping with Open SourceState of the Art Web Mapping with Open Source
State of the Art Web Mapping with Open Source
 
Mongo db dla administratora
Mongo db dla administratoraMongo db dla administratora
Mongo db dla administratora
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)
 
PoEAA by Example
PoEAA by ExamplePoEAA by Example
PoEAA by Example
 

Más de MongoDB

MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump StartMongoDB
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB
 
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDBMongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDBMongoDB
 

Más de MongoDB (20)

MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
 
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDBMongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
 

Último

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 

Último (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 

Transitioning from SQL to MongoDB

  • 1. #MongoDB Transitioning from SQL to MongoDB Buzz Moschetti buzz.moschetti@mongodb.com Enterprise Architect, MongoDB
  • 2. Before We Begin • This webinar is being recorded • Use The Chat Window for • Technical assistance • Q&A • MongoDB Team will answer quick questions in realtime • “Common” questions will be reviewed at the end of the webinar
  • 3. Who is your Presenter? • Yes, I use “Buzz” on my business cards • Former Investment Bank Chief Architect at JPMorganChase and Bear Stearns before that • Over 27 years of designing and building systems • Big and small • Super-specialized to broadly useful in any vertical • “Traditional” to completely disruptive • Advocate of language leverage and strong factoring • Still programming – using emacs, of course
  • 4. What Are Your Developers Doing All Day? Adding and testing business features OR “Integrating with other components, tools, and systems” • Database(s) • ETL and other data transfer operations • Messaging • Services (web & other) • Other open source frameworks incl. ORMs
  • 5. Why Can’t We Just Save and Fetch Data? Because the way we think about data at the business use case level… …is different than the way it is implemented at the application/code level… …which traditionally is VERY different than the way it is implemented at the database level
  • 6. This Problem Isn’t New… …but for the past 40 years, innovation at the business & application layers has outpaced innovation at the database layer 1974 2014 Business Data Goals Capture my company’s transactions daily at 5:30PM EST, add them up on a nightly basis, and print a big stack of paper Capture my company’s global transactions in realtime plus everything that is happening in the world (customers, competitors, business/regulatory/weather), producing any number of computed results, and passing this all in realtime to predictive analytics with model feedback; results in realtime to 10000s of mobile devices, multiple GUIs, and b2b and b2c channels Release Schedule Semi-Annually Yesterday Application /Code COBOL, Fortran, Algol, PL/1, assembler, proprietary tools C, C++, VB, C#, Java, javascript, groovy, ruby, perl python, Obj-C, SmallTalk, Clojure, ActionScript, Flex, DSLs, spring, AOP, CORBA, ORM, third party software ecosystem, the whole open source movement, … and COBOL and Fortran Database I/VSAM, early RDBMS Mature RDBMS, legacy I/VSAM Column & key/value stores, and…mongoDB
  • 7. Exactly How Does MongoDB Change Things? • MongoDB is designed from the ground up to address rich structure (maps of maps of lists of…), not rectangles • Standard RDBMS interfaces (i.e. JDBC) do not exploit features of contemporary languages • Rapid Application Development (RAD) and scripting in Javascript, Python, Perl, Ruby, and Scala is impedance-matched to mongoDB • In MongoDB, the data is the schema • Shapes of data go in the same way they come out
  • 8. Rectangles are 1974. Maps and Lists are 2014 { customer_id : 1, first_name : "Mark", last_name : "Smith", city : "San Francisco", phones: [ { type : “work”, number: “1-800-555-1212” }, { type : “home”, number: “1-800-555-1313”, DNC: true }, { type : “home”, number: “1-800-555-1414”, DNC: true } ] }
  • 9. An Actual Code Example (Finally!) Let’s compare and contrast RDBMS/SQL to MongoDB development using Java over the course of a few weeks. Some ground rules: 1. Observe rules of Software Engineering 101: Assume separation of application, Data Access Layer, and persistor implementation 2. Data Access Layer must be able to a. Expose simple, functional, data-only interfaces to the application • No ORM, frameworks, compile-time bindings, special tools b. Exploit high performance features of persistor 3. Focus on core data handling code and avoid distractions that require the same amount of work in both technologies a. No exception or error handling b. Leave out DB connection and other setup resources 4. Day counts are a proxy for progress, not actual time to complete indicated task
  • 10. The Task: Saving and Fetching Contact data Map m = new HashMap(); m.put(“name”, “buzz”); m.put(“id”, “K1”); Start with this simple, flat shape in the Data Access Layer: save(Map m) And assume we save it in this way: Map m = fetch(String id) And assume we fetch one by primary key in this way: Brace yourself…..
  • 11. Day 1: Initial efforts for both technologies SQL DDL: create table contact ( … ) init() { contactInsertStmt = connection.prepareStatement (“insert into contact ( id, name ) values ( ?,? )”); fetchStmt = connection.prepareStatement (“select id, name from contact where id = ?”); } save(Map m) { contactInsertStmt.setString(1, m.get(“id”)); contactInsertStmt.setString(2, m.get(“name”)); contactInsertStmt.execute(); } Map fetch(String id) { Map m = null; fetchStmt.setString(1, id); rs = fetchStmt.execute(); if(rs.next()) { m = new HashMap(); m.put(“id”, rs.getString(1)); m.put(“name”, rs.getString(2)); } return m; } MongoDB DDL: none save(Map m) { collection.insert(m); } Map fetch(String id) { Map m = null; DBObject dbo = new BasicDBObject(); dbo.put(“id”, id); c = collection.find(dbo); if(c.hasNext()) } m = (Map) c.next(); } return m; }
  • 12. Day 2: Add simple fields m.put(“name”, “buzz”); m.put(“id”, “K1”); m.put(“title”, “Mr.”); m.put(“hireDate”, new Date(2011, 11, 1)); • Capturing title and hireDate is part of adding a new business feature • It was pretty easy to add two fields to the structure • …but now we have to change our persistence code Brace yourself (again) …..
  • 13. SQL Day 2 (changes in bold) DDL: alter table contact add title varchar(8); alter table contact add hireDate date; init() { contactInsertStmt = connection.prepareStatement (“insert into contact ( id, name, title, hiredate ) values ( ?,?,?,? )”); fetchStmt = connection.prepareStatement (“select id, name, title, hiredate from contact where id = ?”); } save(Map m) { contactInsertStmt.setString(1, m.get(“id”)); contactInsertStmt.setString(2, m.get(“name”)); contactInsertStmt.setString(3, m.get(“title”)); contactInsertStmt.setDate(4, m.get(“hireDate”)); contactInsertStmt.execute(); } Map fetch(String id) { Map m = null; fetchStmt.setString(1, id); rs = fetchStmt.execute(); if(rs.next()) { m = new HashMap(); m.put(“id”, rs.getString(1)); m.put(“name”, rs.getString(2)); m.put(“title”, rs.getString(3)); m.put(“hireDate”, rs.getDate(4)); } return m; } Consequences: 1. Code release schedule linked to database upgrade (new code cannot run on old schema) 2. Issues with case sensitivity starting to creep in (many RDBMS are case insensitive for column names, but code is case sensitive) 3. Changes require careful mods in 4 places 4. Beginning of technical debt
  • 14. MongoDB Day 2 save(Map m) { collection.insert(m); } Map fetch(String id) { Map m = null; DBObject dbo = new BasicDBObject(); dbo.put(“id”, id); c = collection.find(dbo); if(c.hasNext()) } m = (Map) c.next(); } return m; } Advantages: 1. Zero time and money spent on overhead code 2. Code and database not physically linked 3. New material with more fields can be added into existing collections; backfill is optional 4. Names of fields in database precisely match key names in code layer and directly match on name, not indirectly via positional offset 5. No technical debt is created ✔ NO CHANGE
  • 15. Day 3: Add list of phone numbers m.put(“name”, “buzz”); m.put(“id”, “K1”); m.put(“title”, “Mr.”); m.put(“hireDate”, new Date(2011, 11, 1)); n1.put(“type”, “work”); n1.put(“number”, “1-800-555-1212”)); list.add(n1); n2.put(“type”, “home”)); n2.put(“number”, “1-866-444-3131”)); list.add(n2); m.put(“phones”, list); • It was still pretty easy to add this data to the structure • .. but meanwhile, in the persistence code … REALLY brace yourself…
  • 16. SQL Day 3 changes: Option 1: Assume just 1 work and 1 home phone number DDL: alter table contact add work_phone varchar(16); alter table contact add home_phone varchar(16); init() { contactInsertStmt = connection.prepareStatement (“insert into contact ( id, name, title, hiredate, work_phone, home_phone ) values ( ?,?,?,?,?,? )”); fetchStmt = connection.prepareStatement (“select id, name, title, hiredate, work_phone, home_phone from contact where id = ?”); } save(Map m) { contactInsertStmt.setString(1, m.get(“id”)); contactInsertStmt.setString(2, m.get(“name”)); contactInsertStmt.setString(3, m.get(“title”)); contactInsertStmt.setDate(4, m.get(“hireDate”)); for(Map onePhone : m.get(“phones”)) { String t = onePhone.get(“type”); String n = onePhone.get(“number”); if(t.equals(“work”)) { contactInsertStmt.setString(5, n); } else if(t.equals(“home”)) { contactInsertStmt.setString(6, n); } } contactInsertStmt.execute(); } Map fetch(String id) { Map m = null; fetchStmt.setString(1, id); rs = fetchStmt.execute(); if(rs.next()) { m = new HashMap(); m.put(“id”, rs.getString(1)); m.put(“name”, rs.getString(2)); m.put(“title”, rs.getString(3)); m.put(“hireDate”, rs.getDate(4)); Map onePhone; onePhone = new HashMap(); onePhone.put(“type”, “work”); onePhone.put(“number”, rs.getString(5)); list.add(onePhone); onePhone = new HashMap(); onePhone.put(“type”, “home”); onePhone.put(“number”, rs.getString(6)); list.add(onePhone); m.put(“phones”, list); } This is just plain bad….
  • 17. SQL Day 3 changes: Option 2: Proper approach with multiple phone numbers DDL: create table phones ( … ) init() { contactInsertStmt = connection.prepareStatement (“insert into contact ( id, name, title, hiredate ) values ( ?,?,?,? )”); c2stmt = connection.prepareStatement(“insert into phones (id, type, number) values (?, ?, ?)”; fetchStmt = connection.prepareStatement (“select id, name, title, hiredate, type, number from contact, phones where phones.id = contact.id and contact.id = ?”); } save(Map m) { startTrans(); contactInsertStmt.setString(1, m.get(“id”)); contactInsertStmt.setString(2, m.get(“name”)); contactInsertStmt.setString(3, m.get(“title”)); contactInsertStmt.setDate(4, m.get(“hireDate”)); for(Map onePhone : m.get(“phones”)) { c2stmt.setString(1, m.get(“id”)); c2stmt.setString(2, onePhone.get(“type”)); c2stmt.setString(3, onePhone.get(“number”)); c2stmt.execute(); } contactInsertStmt.execute(); endTrans(); } Map fetch(String id) { Map m = null; fetchStmt.setString(1, id); rs = fetchStmt.execute(); int i = 0; List list = new ArrayList(); while (rs.next()) { if(i == 0) { m = new HashMap(); m.put(“id”, rs.getString(1)); m.put(“name”, rs.getString(2)); m.put(“title”, rs.getString(3)); m.put(“hireDate”, rs.getDate(4)); m.put(“phones”, list); } Map onePhone = new HashMap(); onePhone.put(“type”, rs.getString(5)); onePhone.put(“number”, rs.getString(6)); list.add(onePhone); i++; } return m; } This took time and money
  • 18. SQL Day 5: Zombies! (zero or more between entities) init() { contactInsertStmt = connection.prepareStatement (“insert into contact ( id, name, title, hiredate ) values ( ?,?,?,? )”); c2stmt = connection.prepareStatement(“insert into phones (id, type, number) values (?, ?, ?)”; fetchStmt = connection.prepareStatement (“select A.id, A.name, A.title, A.hiredate, B.type, B.number from contact A left outer join phones B on (A.id = B. id) where A.id = ?”); } Whoops! And it’s also wrong! We did not design the query accounting for contacts that have no phone number. Thus, we have to change the join to an outer join. But this ALSO means we have to change the unwind logic This took more time and money! while (rs.next()) { if(i == 0) { // … } String s = rs.getString(5); if(s != null) { Map onePhone = new HashMap(); onePhone.put(“type”, s); onePhone.put(“number”, rs.getString(6)); list.add(onePhone); } } …but at least we have a DAL… right?
  • 19. MongoDB Day 3 Advantages: 1. Zero time and money spent on overhead code 2. No need to fear fields that are “naturally occurring” lists containing data specific to the parent structure and thus do not benefit from normalization and referential integrity 3. Safe from zombies and other undead distractions from productivity save(Map m) { collection.insert(m); } Map fetch(String id) { Map m = null; DBObject dbo = new BasicDBObject(); dbo.put(“id”, id); c = collection.find(dbo); if(c.hasNext()) } m = (Map) c.next(); } return m; } ✔ NO CHANGE
  • 20. By Day 14, our structure looks like this: n4.put(“geo”, “US-EAST”); n4.put(“startupApps”, new String[] { “app1”, “app2”, “app3” } ); list2.add(n4); n4.put(“geo”, “EMEA”); n4.put(“startupApps”, new String[] { “app6” } ); n4.put(“useLocalNumberFormats”, false): list2.add(n4); m.put(“preferences”, list2) n6.put(“optOut”, true); n6.put(“assertDate”, someDate); seclist.add(n6); m.put(“attestations”, seclist) m.put(“security”, mapOfDataCreatedByExternalSource); • It was still pretty easy to add this data to the structure • Want to guess what the SQL persistence code looks like? • How about the MongoDB persistence code?
  • 21. SQL Day 14 Error: Could not fit all the code into this space. …actually, I didn’t want to spend 2 hours putting the code together.. But very likely, among other things: • n4.put(“startupApps”,new String[]{“app1”,“app2”,“app3”}); was implemented as a single semi-colon delimited string • m.put(“security”, anotherMapOfData); was implemented by flattening it out and storing a subset of fields
  • 22. MongoDB Day 14 – and every other day Advantages: 1. Zero time and money spent on overhead code 2. Persistence is so easy and flexible and backward compatible that the persistor does not upward-influence the shapes we want to persist i.e. the tail does not wag the dog save(Map m) { collection.insert(m); } Map fetch(String id) { Map m = null; DBObject dbo = new BasicDBObject(); dbo.put(“id”, id); c = collection.find(dbo); if(c.hasNext()) } m = (Map) c.next(); } return m; } ✔ NO CHANGE
  • 23. But what if we must do a join? Both RDBMS and MongoDB will have a PhoneTransactions table/collection { customer_id : 1, first_name : "Mark", last_name : "Smith", city : "San Francisco", phones: [ { type : “work”, number: “1-800-555-1212” }, { type : “home”, number: “1-800-555-1313”, DNC: true }, { type : “home”, number: “1-800-555-1414”, DNC: true } ] } { number: “1-800-555-1212”, target: “1-999-238-3423”, duration: 20 } { number: “1-800-555-1212”, target: “1-444-785-6611”, duration: 243 } { number: “1-800-555-1414”, target: “1-645-331-4345”, duration: 132 } { number: “1-800-555-1414”, target: “1-990-875-2134”, duration: 71 } PhoneTransactions
  • 24. SQL Join Attempt #1 select A.id, A.lname, B.type, B.number, C.target, C.duration from contact A, phones B, phonestx C Where A.id = B.id and B.number = C.number id | lname | type | number | target | duration -----+--------------+------+----------------+----------------+---------- g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7070 | 23 g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7071 | 7 g9 | Moschetti | work | 1-800-989-2231 | 1-987-707-7072 | 9 g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7071 | 7 g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7070 | 23 g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7071 | 7 g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7070 | 23 g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7072 | 9 g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7072 | 9 g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7072 | 9 How to turn this into a list of names – each with a list of numbers, each of those with a list of target numbers?
  • 25. SQL Unwind Attempt #1 Map idmap = new HashMap(); ResultSet rs = fetchStmt.execute(); while (rs.next()) { String id = rs.getString(“id"); String nmbr = rs.getString("number"); List tnum; Map snum; if((snum = (List) idmap.get(id)) == null) { snum = new HashMap(); idmap.put(did, snum); } if((tnum = snum.get(nmbr)) == null) { tnum = new ArrayList(); snum.put(number, tnum); } Map info = new HashMap(); info.put("target", rs.getString("target")); info.put("duration", rs.getInteger("duration")); tnum.add(info); } // idmap[“g9”][“1-900-555-1212”] = ({target:1-222-707-7070,duration:23…)
  • 26. SQL Join Attempt #2 select A.id, A.lname, B.type, B.number, C.target, C.duration Fromcontact A, phones B, phonestx C Where A.id = B.id and B.number = C.number order by A.id, B.number id | lname | type | number | target | duration -----+--------------+------+----------------+----------------+---------- g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7072 | 9 g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7070 | 23 g10 | Kalan | work | 1-999-444-9999 | 1-222-907-7071 | 7 g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7072 | 9 g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7070 | 23 g9 | Moschetti | home | 1-777-999-1212 | 1-222-807-7071 | 7 g9 | Moschetti | work | 1-800-989-2231 | 1-987-707-7072 | 9 g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7071 | 7 g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7072 | 9 g9 | Moschetti | home | 1-900-555-1212 | 1-222-707-7070 | 23 “Early bail out” from cursor is now possible – but logic to construct list of source and target numbers is similar
  • 27. SQL is about Disassembly String s = “select A, B, C, D, E, F from T1,T2,T3 where T1.col = T2.col and T2.col2 = T3.col2 and X = Y and X2 != Y2 and G > 10 and G < 100 and TO_DATE(‘ …”; ResultSet rs = execute(s); while(ResultSet.next()) { if(new column1 value from T1) { set up new Object; } if(new column2 value from T2) { set up new Object2 } if(new column3 value from T3) { set up new Object3 } populate maps, lists and scalars } Design a Big Query including business logic to grab all the data up front Throw it at the engine Disassemble Big Rectangle into usable objects with logic implicit in change in column values
  • 28. MongoDB is about Assembly Cursor c = coll1.find({“X”:”Y”}); while(c.hasNext()) { populate maps, lists and scalars; Cursor c2 = coll2.find(logic+key from c); while(c2.hasNext()) { populate maps, lists and scalars; Cursor c3 = coll3.find(logic+key from c2); while(c3.hasNext()) { populate maps, lists and scalars; } } Assemble usable objects incrementally with explicit logic
  • 29. MongoDB ”Join” Map idmap = new HashMap(); DBCursor c = contacts.find(); while(c.hasNext()) { DBObject item = c.next(); String id = item.get(“id”); Map nummap = new HashMap(); for(Map phone : (List)item.get(”phones”)) { String pnum = phone.get(“number”); DBObject q = new BasicDBObject(“number”, pnum); DBCursor c2 = phonestx.find(q); List txs = new ArrayList(); while(c2.hasNext()) { txs.add((Map)c2.next()); } nummap.put(pnum, txs); } idmap.put(id, nummap); } // idmap[“g9”][“1-900-555-1212”] = ({target:1-222-707-7070,duration:23…)
  • 30. But what about “real” queries? • MongoDB query language is a physical map-of-map based structure, not a String • Operators (e.g. AND, OR, GT, EQ, etc.) and arguments are keys and values in a cascade of Maps • No grammar to parse, no templates to fill in, no whitespace, no escaping quotes, no parentheses, no punctuation • Same paradigm to manipulate data is used to manipulate query expressions • …which is also, by the way, the same paradigm for working with MongoDB metadata and explain()
  • 31. MongoDB Query Examples Find all contacts with at least one work phone SQL CLI select * from contact A, phones B where A.did = B.did and B.type = 'work’; MongoDB CLI db.contact.find({"phones.type”:”work”}); SQL in Java String s = “select * from contact A, phones B where A.did = B.did and B.type = 'work’”; ResultSet rs = execute(s); MongoDB via Java driver DBObject expr = new BasicDBObject(); expr.put(“phones.type”, “work”); Cursor c = contact.find(expr);
  • 32. MongoDB Query Examples Find all contacts with at least one work phone or hired after 2014-02-02 SQL select A.did, A.lname, A.hiredate, B.type, B.number from contact A left outer join phones B on (B.did = A.did) where b.type = 'work' or A.hiredate > '2014-02-02'::date MongoDB CLI db.contacts.find({"$or”: [ {"phones.number":"1-900-555- 1212”}, {"hireda te": {”$gt": new ISODate("2014-02-02")}} ]});
  • 33. MongoDB Query Examples Find all contacts with at least one work phone or hired after 2014-02-02 MongoDB via Java driver List arr = new ArrayList(); Map phones = new HashMap(); phones.put(“phones.type”, “work”); arr.add(phones); Map hdate = new HashMap(); java.util.Date d = dateFromStr(“2014-02-02”); hdate.put(“hiredate”, new BasicDBObject(“$gt”,d)); Map m1 = new HashMap(); m1.put(“$or”, arr); contact.find(new BasicDBObject(m1));
  • 34. …and before you ask… Yes, MongoDB query expressions support 1. Sorting 2. Cursor size limit 3. Projection (asking for only parts of the rich shape to be returned) 4. Aggregation (“GROUP BY”) functions
  • 35. Day 30: RAD on MongoDB with Python import pymongo def save(data): coll.insert(data) def fetch(id): return coll.find_one({”id": id } ) myData = { “name”: “jane”, “id”: “K2”, # no title? No problem “hireDate”: datetime.date(2011, 11, 1), “phones”: [ { "type": "work", "number": "1-800-555-1212" }, { "type": "home", "number": "1-866-444-3131" } ] } save(myData) print fetch(“K2”) expr = {"$or": [ {"phones.type": “work”}, {”hiredate": {“$gt”: datetime.date(2014,2,2)}} ]} for c in coll.find(expr): print [ k.upper() for k in sorted(c.keys()) ] Advantages: 1. Far easier and faster to create scripts due to “fidelity-parity” of mongoDB map data and python (and perl, ruby, and javascript) structures 1. Data types and structure in scripts are exactly the same as that read and written in Java and C++
  • 36. Day 30: Polymorphic RAD on MongoDB with Python import pymongo item = fetch("K8") # item is: { “name”: “bob”, “id”: “K8”, "personalData": { "preferedAirports": [ "LGA", "JFK" ], "travelTimeThreshold": { "value": 3, "units": “HRS”} } } item = fetch("K9") # item is: { “name”: “steve”, “id”: “K9”, "personalData": { "lastAccountVisited": { "name": "mongoDB", "when": datetime.date(2013,11,4) }, "favoriteNumber": 3.14159 } } Advantages: 1. Scripting languages easily digest shapes with common fields and dissimilar fields 2. Easy to create an information architecture where placeholder fields like personalData are “known” in the software logic to be dynamic
  • 37. Day 30: (Not) RAD on top of SQL with Python init() { contactInsertStmt = connection.prepareStatement (“insert into contact ( id, name, title, hiredate ) values ( ?,?,?,? )”); c2stmt = connection.prepareStatement(“insert into phones (id, type, number) values (?, ?, ?)”; fetchStmt = connection.prepareStatement (“select id, name, title, hiredate, type, number from contact, phones where phones.id = contact.id and contact.id = ?”); } save(Map m) { startTrans(); contactInsertStmt.setString(1, m.get(“id”)); contactInsertStmt.setString(2, m.get(“name”)); contactInsertStmt.setString(3, m.get(“title”)); contactInsertStmt.setDate(4, m.get(“hireDate”)); for(Map onePhone : m.get(“phones”)) { c2stmt.setString(1, onePhone.get(“type”)); c2stmt.setString(2, onePhone.get(“number”)); c2stmt.execute(); } contactInsertStmt.execute(); endTrans(); } Consequences: 1. All logic coded in Java interface layer (unwinding contact, phones, preferences, etc.) needs to be rewritten in python (unless Jython is used) … AND/or perl, C++, Scala, etc. 2. No robust way to handle polymorphic data other than BLOBing it 3. …and that will take real time and money!
  • 38. The Fundamental Change with mongoDB RDBMS designed in era when: • CPU and disk was slow & expensive • Memory was VERY expensive • Network? What network? • Languages had limited means to dynamically reflect on their types • Languages had poor support for richly structured types Thus, the database had to • Act as combiner-coordinator of simpler types • Define a rigid schema • (Together with the code) optimize at compile-time, not run-time In mongoDB, the data is the schema!
  • 39. mongoDB and the Rich Map Ecosystem Generic comparison of two records Map expr = new HashMap(); expr.put("myKey", "K1"); DBObject a = collection.findOne(expr); expr.put("myKey", "K2"); DBObject b = collection.findOne(expr); List<MapDiff.Difference> d = MapDiff.diff((Map)a, (Map)b); Getting default values for a thing on a certain date and then overlaying user preferences (like for a calculation run) Map expr = new HashMap(); expr.put("myKey", "DEFAULT"); expr.put("createDate", new Date(2013, 11, 1)); DBObject a = collection.findOne(expr); expr.clear(); expr.put("myKey", "user1"); DBObject b = otherCollectionPerhaps.findOne(expr); MapStack s = new MapStack(); s.push((Map)a); s.push((Map)b); Map merged = s.project(); Runtime reflection of Maps and Lists enables generic powerful utilities (MapDiff, MapStack) to be created once and used for all kinds of shapes, saving time and money
  • 40. Lastly: A CLI with teeth > db.contact.find({"SeqNum": {"$gt”:10000}}).explain(); { "cursor" : "BasicCursor", "n" : 200000, //... "millis" : 223 } Try a query and show the diagnostics > for(v=[],i=0;i<3;i++) { … n = i*50000; … expr = {"SeqNum": {"$gt”: n}}; … v.push( [n, db.contact.find(expr).explain().millis)] } Run it 3 times with smaller and smaller chunks and create a vector of timing result pairs (size,time) > v [ [ 0, 225 ], [ 50000, 222 ], [ 100000, 220 ] ] Let’s see that vector > load(“jStat.js”) > jStat.stdev(v.map(function(p){return p[1];})) 2.0548046676563256 Use any other javascript you want inside the shell > for(i=0;i<3;i++) { … expr = {"SeqNum": {"$gt":i*1000}}; … db.foo.insert(db.contact.find(expr).explain()); } Party trick: save the explain() output back into a collection!
  • 41. What Does All This Add Up To? • MongoDB easier than RDBMS/SQL for real problems • Quicker to change • Much better harmonized with modern languages + • Comprehensive indexing (arbitrary non/unique secondaries, compound keys, geospatial, text search, TTL, etc….) • Horizontally scalable to petabytes • Isomorphic HA and DR Modern Database for Modern Solutions =
  • 43. #MongoDB Thank You Buzz Moschetti buzz.moschetti@mongodb.com Enterprise Architect, MongoDB

Notas del editor

  1. CONSEQUENCE: Logic split across SQL query and disassembly FURTHER complicated with prepared statements & paramterization because it splits up the Big Query
  2. Far less time required to set up complex, dynamic, parameterized filters No need for SQL rewrite logic or creating new PreparedStatements Map-of-Maps query structure (m1) is easily walked and processed without parsing