zero to mongo in 60 hours

159
Zero to Mongo in 60 Hours Ryan Angilly MyPunchbowl.com @angilly Wednesday, April 28, 2010

Upload: mongosf

Post on 15-May-2015

9.496 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Zero to Mongo in 60 Hours

Zero to Mongo in 60 Hours

Ryan AngillyMyPunchbowl.com

@angilly

Wednesday, April 28, 2010

Page 2: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

Wednesday, April 28, 2010

Page 3: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

Wednesday, April 28, 2010

Page 4: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

Wednesday, April 28, 2010

Page 5: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

Wednesday, April 28, 2010

Page 6: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

Wednesday, April 28, 2010

Page 7: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

• Senior developer @ MyPunchbowl.com

Wednesday, April 28, 2010

Page 8: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

• Senior developer @ MyPunchbowl.com

• Built several web apps

Wednesday, April 28, 2010

Page 9: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

• Senior developer @ MyPunchbowl.com

• Built several web apps

• All Ruby. Mostly Rails

Wednesday, April 28, 2010

Page 10: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

• Senior developer @ MyPunchbowl.com

• Built several web apps

• All Ruby. Mostly Rails

• All SQL

Wednesday, April 28, 2010

Page 11: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

• Senior developer @ MyPunchbowl.com

• Built several web apps

• All Ruby. Mostly Rails

• All SQL

• No experience w/ NoSQL/Mongo as of September ’09

Wednesday, April 28, 2010

Page 12: Zero to Mongo in 60 Hours

I’m a pretty awesome dude

• Electrical Engineer by education

• Ex-EMC’er

• Founded MessageSling.com

• Entered the deadpool in January

• Senior developer @ MyPunchbowl.com

• Built several web apps

• All Ruby. Mostly Rails

• All SQL

• No experience w/ NoSQL/Mongo as of September ’09

• Want to provide a beginner’s perspective

Wednesday, April 28, 2010

Page 13: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

Wednesday, April 28, 2010

Page 14: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

Wednesday, April 28, 2010

Page 15: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

• Connecting party planners to party vendors -- subject of this talk

Wednesday, April 28, 2010

Page 16: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

• Connecting party planners to party vendors -- subject of this talk

• Currently employs 11 people

Wednesday, April 28, 2010

Page 17: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

• Connecting party planners to party vendors -- subject of this talk

• Currently employs 11 people

• Funded over 2 rounds by Intel & Contour

Wednesday, April 28, 2010

Page 18: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

• Connecting party planners to party vendors -- subject of this talk

• Currently employs 11 people

• Funded over 2 rounds by Intel & Contour

• Strategic partnership w/ OTC among others

Wednesday, April 28, 2010

Page 19: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

• Connecting party planners to party vendors -- subject of this talk

• Currently employs 11 people

• Funded over 2 rounds by Intel & Contour

• Strategic partnership w/ OTC among others

• Amount of traffic, users, events, invites, vendors, etc... make our data sets large enough to be interesting :)

Wednesday, April 28, 2010

Page 20: Zero to Mongo in 60 Hours

MyPunchbowl is a pretty awesome company

• Leader in start to finish party planning

• Connecting party planners to party vendors -- subject of this talk

• Currently employs 11 people

• Funded over 2 rounds by Intel & Contour

• Strategic partnership w/ OTC among others

• Amount of traffic, users, events, invites, vendors, etc... make our data sets large enough to be interesting :)

• We’re talking many millions of ‘things’

Wednesday, April 28, 2010

Page 21: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 22: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 23: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 24: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 25: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 26: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 27: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 28: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 29: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 30: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 31: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 32: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 33: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 34: Zero to Mongo in 60 Hours

Our engineers play with everything

Wednesday, April 28, 2010

Page 35: Zero to Mongo in 60 Hours

Wednesday, April 28, 2010

Page 36: Zero to Mongo in 60 Hours

Search by category and location

Wednesday, April 28, 2010

Page 37: Zero to Mongo in 60 Hours

Search by category and location

Search by business name and location

Wednesday, April 28, 2010

Page 38: Zero to Mongo in 60 Hours

Wednesday, April 28, 2010

Page 39: Zero to Mongo in 60 Hours

Track searches

Wednesday, April 28, 2010

Page 40: Zero to Mongo in 60 Hours

Track searches

Track vendor impressions

Wednesday, April 28, 2010

Page 41: Zero to Mongo in 60 Hours

MongoDB + MyPunchbowl

A tale in conversations

Wednesday, April 28, 2010

Page 42: Zero to Mongo in 60 Hours

Tracking requirement a good excuse to finally use MongoDB

Wednesday, April 28, 2010

Page 43: Zero to Mongo in 60 Hours

Tracking requirement a good excuse to finally use MongoDB

Me: Hey Blake I’m gonna use MongoDB to keep track of all this search stuff.

Wednesday, April 28, 2010

Page 44: Zero to Mongo in 60 Hours

Tracking requirement a good excuse to finally use MongoDB

Me: Hey Blake I’m gonna use MongoDB to keep track of all this search stuff.

Blake: Cool.

Wednesday, April 28, 2010

Page 45: Zero to Mongo in 60 Hours

Tracking requirement a good excuse to finally use MongoDB

Me: Hey Blake I’m gonna use MongoDB to keep track of all this search stuff.

Blake: Cool.

Matt (CEO): What’s that?

Wednesday, April 28, 2010

Page 46: Zero to Mongo in 60 Hours

Tracking requirement a good excuse to finally use MongoDB

Me: Hey Blake I’m gonna use MongoDB to keep track of all this search stuff.

Blake: Cool.

Matt (CEO): What’s that?

Blake & Me: Something cool.

Wednesday, April 28, 2010

Page 47: Zero to Mongo in 60 Hours

Tracking requirement a good excuse to finally use MongoDB

Me: Hey Blake I’m gonna use MongoDB to keep track of all this search stuff.

Blake: Cool.

Matt (CEO): What’s that?

Blake & Me: Something cool.

Matt (CEO): K

Wednesday, April 28, 2010

Page 48: Zero to Mongo in 60 Hours

6 reasons to use MongoDB

• Easy to get running (~5 minutes on OSX)

• Open Source

• Support in multiple (computer) languages

• Prototype in Ruby, move to Java if needed

• Very active development

• Full featured

• Great ecosystem

Wednesday, April 28, 2010

Page 49: Zero to Mongo in 60 Hours

MongoDB feels right

Wednesday, April 28, 2010

Page 50: Zero to Mongo in 60 Hours

MongoDB feels right

Me: MongoDB gives me the warm fuzzies that Rails did.

Wednesday, April 28, 2010

Page 51: Zero to Mongo in 60 Hours

MongoDB feels right

Me: MongoDB gives me the warm fuzzies that Rails did.

Darren: Just like that Nunemaker post.

Wednesday, April 28, 2010

Page 52: Zero to Mongo in 60 Hours

MongoDB feels right

Me: MongoDB gives me the warm fuzzies that Rails did.

Darren: Just like that Nunemaker post.

Me: ? *runs to google*

Wednesday, April 28, 2010

Page 53: Zero to Mongo in 60 Hours

MongoDB feels right

Me: MongoDB gives me the warm fuzzies that Rails did.

Darren: Just like that Nunemaker post.

Me: ? *runs to google*

Wednesday, April 28, 2010

Page 54: Zero to Mongo in 60 Hours

Support is INSANE

11:35pm. Wednesday. Founder.60 second response time.

Wednesday, April 28, 2010

Page 55: Zero to Mongo in 60 Hours

2.5 days? Really?

Wednesday, April 28, 2010

Page 56: Zero to Mongo in 60 Hours

2.5 days? Really?

Yes

Wednesday, April 28, 2010

Page 57: Zero to Mongo in 60 Hours

2.5 days? Really?

Yes*

Wednesday, April 28, 2010

Page 58: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days 200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 59: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 60: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 61: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

Figure out document ‘schema’

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 62: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

Figure out document ‘schema’

Write some stuff on top of mongo-ruby-driver

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 63: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

Figure out document ‘schema’

Build test rig

Write some stuff on top of mongo-ruby-driver

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 64: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

Figure out document ‘schema’

Setup Configuration Management

Build test rig

Write some stuff on top of mongo-ruby-driver

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 65: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

Figure out document ‘schema’

Get production ready

Setup Configuration Management

Build test rig

Write some stuff on top of mongo-ruby-driver

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 66: Zero to Mongo in 60 Hours

0 Days 1 Day 2 Days

Decision to use

MongoDB

Play around with available OSS

Figure out document ‘schema’

Get production ready

Setup Configuration Management

Build test rig

Write some stuff on top of mongo-ruby-driver

Deploy

200+ Daysand on...

2.5 days to MongoDB

Wednesday, April 28, 2010

Page 67: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

Wednesday, April 28, 2010

Page 68: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

Wednesday, April 28, 2010

Page 69: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

• mongo shell (JS via SpiderMonkey)

Wednesday, April 28, 2010

Page 70: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

• mongo shell (JS via SpiderMonkey)

• mongo-ruby-driver

Wednesday, April 28, 2010

Page 71: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

• mongo shell (JS via SpiderMonkey)

• mongo-ruby-driver

• mongo-java-driver

Wednesday, April 28, 2010

Page 72: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

• mongo shell (JS via SpiderMonkey)

• mongo-ruby-driver

• mongo-java-driver

• mongo_record (Ruby)

Wednesday, April 28, 2010

Page 73: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

• mongo shell (JS via SpiderMonkey)

• mongo-ruby-driver

• mongo-java-driver

• mongo_record (Ruby)

• mongo_mapper (Ruby)

Wednesday, April 28, 2010

Page 74: Zero to Mongo in 60 Hours

A stroll through Mongo’s OSS ecosystem

• mongodb (C++)

• mongo shell (JS via SpiderMonkey)

• mongo-ruby-driver

• mongo-java-driver

• mongo_record (Ruby)

• mongo_mapper (Ruby)

• Integration w/ Rails

Wednesday, April 28, 2010

Page 75: Zero to Mongo in 60 Hours

Document ‘schema’

Wednesday, April 28, 2010

Page 76: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

Wednesday, April 28, 2010

Page 77: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

• Example Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

Wednesday, April 28, 2010

Page 78: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

• Example Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• How do you update the documents?

Wednesday, April 28, 2010

Page 79: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

• Example Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• How do you update the documents?

• Mongo shell command

coll.update({‘city’: ‘Boston’,

‘state’: ‘MA’,

‘date’: 1272153600,

‘category_id’: 1},

{‘$inc’: {‘occurrences’: 1}},

true)

Wednesday, April 28, 2010

Page 80: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

• Example Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• How do you update the documents?

• Mongo shell command

coll.update({‘city’: ‘Boston’,

‘state’: ‘MA’,

‘date’: 1272153600,

‘category_id’: 1},

{‘$inc’: {‘occurrences’: 1}},

true)

Document to match

Wednesday, April 28, 2010

Page 81: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

• Example Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• How do you update the documents?

• Mongo shell command

coll.update({‘city’: ‘Boston’,

‘state’: ‘MA’,

‘date’: 1272153600,

‘category_id’: 1},

{‘$inc’: {‘occurrences’: 1}},

true)

Document to match

Operation to perform

Wednesday, April 28, 2010

Page 82: Zero to Mongo in 60 Hours

Document ‘schema’

• What do documents look like?

• Example Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• How do you update the documents?

• Mongo shell command

coll.update({‘city’: ‘Boston’,

‘state’: ‘MA’,

‘date’: 1272153600,

‘category_id’: 1},

{‘$inc’: {‘occurrences’: 1}},

true)

Document to match

Operation to perform

‘upsert’: update if it’s there

insert if it’s not

Wednesday, April 28, 2010

Page 83: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

Wednesday, April 28, 2010

Page 84: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

Wednesday, April 28, 2010

Page 85: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

Wednesday, April 28, 2010

Page 86: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

Wednesday, April 28, 2010

Page 87: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

Wednesday, April 28, 2010

Page 88: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

• Flexibility & performance inquerying and aggregating

Wednesday, April 28, 2010

Page 89: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

• Flexibility & performance inquerying and aggregating

• More Complex Document w/ Embedded Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 9581555,

category_id: 1,

mobile_sources: {

browsers: {

windows_mobile: 1,

palm_os: 0,

iphone_4g: 9481554

},

zip_codes: [“01518”]

}

}

Wednesday, April 28, 2010

Page 90: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

• Flexibility & performance inquerying and aggregating

• More Complex Document w/ Embedded Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 9581555,

category_id: 1,

mobile_sources: {

browsers: {

windows_mobile: 1,

palm_os: 0,

iphone_4g: 9481554

},

zip_codes: [“01518”]

}

}

• Additional, complex data down the road?

Wednesday, April 28, 2010

Page 91: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

• Flexibility & performance inquerying and aggregating

• More Complex Document w/ Embedded Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 9581555,

category_id: 1,

mobile_sources: {

browsers: {

windows_mobile: 1,

palm_os: 0,

iphone_4g: 9481554

},

zip_codes: [“01518”]

}

}

• Additional, complex data down the road?

• Add deep embedded indexes!

Wednesday, April 28, 2010

Page 92: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

• Flexibility & performance inquerying and aggregating

• More Complex Document w/ Embedded Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 9581555,

category_id: 1,

mobile_sources: {

browsers: {

windows_mobile: 1,

palm_os: 0,

iphone_4g: 9481554

},

zip_codes: [“01518”]

}

}

• Additional, complex data down the road?

• Add deep embedded indexes!

• ‘mobile_sources.zip_codes’

Wednesday, April 28, 2010

Page 93: Zero to Mongo in 60 Hours

Cuhhraazy Indexes

• Original Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 1,

category_id: 1

}

• 40k cities, 200 days, 60 categories

• 480M potential documents

• Composite indexes

• state_1_city_1

• state_1_date_1_city_1

• category_id_1_date_1

• date_1

• Flexibility & performance inquerying and aggregating

• More Complex Document w/ Embedded Document

{

city: “Boston”,

state: “MA”,

date: 1272153600,

occurrences: 9581555,

category_id: 1,

mobile_sources: {

browsers: {

windows_mobile: 1,

palm_os: 0,

iphone_4g: 9481554

},

zip_codes: [“01518”]

}

}

• Additional, complex data down the road?

• Add deep embedded indexes!

• ‘mobile_sources.zip_codes’

• ‘mobile_sources.browsers.iphone_4g’

Wednesday, April 28, 2010

Page 94: Zero to Mongo in 60 Hours

Let’s write some Ruby

Wednesday, April 28, 2010

Page 95: Zero to Mongo in 60 Hours

Let’s write some Rubyclass SearchStats

cattr_accessor :db, :collection

self.collection = $mongo_db.collection ‘searches‘

def self.record_search(city, state, category_id, vendor_id)

collection.update({:vendor_id => vendor_id,

:city => city,

:state => state,

:category_id => category_id,

:date => Time.now.utc.beginning_of_day.to_i},

{'$inc' => {:occurrence => 1}},

{:upsert => true})

end

end

Wednesday, April 28, 2010

Page 96: Zero to Mongo in 60 Hours

Let’s write some Rubyclass SearchStats

cattr_accessor :db, :collection

self.collection = $mongo_db.collection ‘searches‘

def self.record_search(city, state, category_id, vendor_id)

collection.update({:vendor_id => vendor_id,

:city => city,

:state => state,

:category_id => category_id,

:date => Time.now.utc.beginning_of_day.to_i},

{'$inc' => {:occurrence => 1}},

{:upsert => true})

end

end

irb> SearchStats.record_search(‘Boston’, ‘MA’, 9, 42)

Wednesday, April 28, 2010

Page 97: Zero to Mongo in 60 Hours

Let’s write some Rubyclass SearchStats

cattr_accessor :db, :collection

self.collection = $mongo_db.collection ‘searches‘

def self.record_search(city, state, category_id, vendor_id)

collection.update({:vendor_id => vendor_id,

:city => city,

:state => state,

:category_id => category_id,

:date => Time.now.utc.beginning_of_day.to_i},

{'$inc' => {:occurrence => 1}},

{:upsert => true})

end

end

irb> SearchStats.record_search(‘Boston’, ‘MA’, 9, 42)

mongo> db.searches.findOne()

{ "city" : "Boston",

"date" : 1272326400,

"impression" : 1,

"category_id" : 9,

"state" : "MA",

"vendor_id" : 42 }

Wednesday, April 28, 2010

Page 98: Zero to Mongo in 60 Hours

TESTING

Wednesday, April 28, 2010

Page 99: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

Wednesday, April 28, 2010

Page 100: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

Wednesday, April 28, 2010

Page 101: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

• config/environments/test.rb

Wednesday, April 28, 2010

Page 102: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

• config/environments/test.rb

• $mongo_db = Mongo::Connection.new.db ‘mongo-sf-db’

Wednesday, April 28, 2010

Page 103: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

• config/environments/test.rb

• $mongo_db = Mongo::Connection.new.db ‘mongo-sf-db’

• SearchStatsTest#setup & #teardown

Wednesday, April 28, 2010

Page 104: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

• config/environments/test.rb

• $mongo_db = Mongo::Connection.new.db ‘mongo-sf-db’

• SearchStatsTest#setup & #teardown

• No transactions

Wednesday, April 28, 2010

Page 105: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

• config/environments/test.rb

• $mongo_db = Mongo::Connection.new.db ‘mongo-sf-db’

• SearchStatsTest#setup & #teardown

• No transactions

• ActiveSupport spoils us

Wednesday, April 28, 2010

Page 106: Zero to Mongo in 60 Hours

TESTING• Pretty much the same as anything else

• test/unit/search_stats_test.rb

• config/environments/test.rb

• $mongo_db = Mongo::Connection.new.db ‘mongo-sf-db’

• SearchStatsTest#setup & #teardown

• No transactions

• ActiveSupport spoils us

• Gotta clean up after yourself

Wednesday, April 28, 2010

Page 107: Zero to Mongo in 60 Hours

Other developers gotta use it too

Wednesday, April 28, 2010

Page 108: Zero to Mongo in 60 Hours

Other developers gotta use it too

• Rails’ database.yml takes care of MySQL

Wednesday, April 28, 2010

Page 109: Zero to Mongo in 60 Hours

Other developers gotta use it too

• Rails’ database.yml takes care of MySQL

• Gotta switch up MongoDBs on your own

Wednesday, April 28, 2010

Page 110: Zero to Mongo in 60 Hours

Other developers gotta use it too

• Rails’ database.yml takes care of MySQL

• Gotta switch up MongoDBs on your own

• Simple config system file inspired by another Nunemaker post.

Wednesday, April 28, 2010

Page 111: Zero to Mongo in 60 Hours

Other developers gotta use it too

• Rails’ database.yml takes care of MySQL

• Gotta switch up MongoDBs on your own

• Simple config system file inspired by another Nunemaker post.

• No database migrations!

Wednesday, April 28, 2010

Page 112: Zero to Mongo in 60 Hours

Other developers gotta use it too

• Rails’ database.yml takes care of MySQL

• Gotta switch up MongoDBs on your own

• Simple config system file inspired by another Nunemaker post.

• No database migrations!

• Must write rake tasks to create indexes unless your ORM takes care of it for you

Wednesday, April 28, 2010

Page 113: Zero to Mongo in 60 Hours

Making production ready

Wednesday, April 28, 2010

Page 114: Zero to Mongo in 60 Hours

Making production ready

• Replication was iffy in 1.0.0 (solid now)

Wednesday, April 28, 2010

Page 115: Zero to Mongo in 60 Hours

Making production ready

• Replication was iffy in 1.0.0 (solid now)

• Nightly dumps w/ mongoexport

Wednesday, April 28, 2010

Page 116: Zero to Mongo in 60 Hours

Making production ready

• Replication was iffy in 1.0.0 (solid now)

• Nightly dumps w/ mongoexport

• Upload to S3

Wednesday, April 28, 2010

Page 117: Zero to Mongo in 60 Hours

Making production ready

• Replication was iffy in 1.0.0 (solid now)

• Nightly dumps w/ mongoexport

• Upload to S3

• Monitor process w/ monit

Wednesday, April 28, 2010

Page 118: Zero to Mongo in 60 Hours

Deploy

Wednesday, April 28, 2010

Page 119: Zero to Mongo in 60 Hours

Deploy

• Original deployment uneventful

Wednesday, April 28, 2010

Page 120: Zero to Mongo in 60 Hours

Deploy

• Original deployment uneventful

• Just worked

Wednesday, April 28, 2010

Page 121: Zero to Mongo in 60 Hours

Deploy

• Original deployment uneventful

• Just worked

• Future deployments that required a database upgrade required downtime (bummer)

Wednesday, April 28, 2010

Page 122: Zero to Mongo in 60 Hours

Deploy

• Original deployment uneventful

• Just worked

• Future deployments that required a database upgrade required downtime (bummer)

• We wanted to play with the geospatial search

Wednesday, April 28, 2010

Page 123: Zero to Mongo in 60 Hours

Day 200

Wednesday, April 28, 2010

Page 124: Zero to Mongo in 60 Hours

Day 200

• One production process

Wednesday, April 28, 2010

Page 125: Zero to Mongo in 60 Hours

Day 200

• One production process

• One database

Wednesday, April 28, 2010

Page 126: Zero to Mongo in 60 Hours

Day 200

• One production process

• One database

• Daily dumps using mongoexport + upload to S3

Wednesday, April 28, 2010

Page 127: Zero to Mongo in 60 Hours

Day 200

• One production process

• One database

• Daily dumps using mongoexport + upload to S3

• Replication not running

Wednesday, April 28, 2010

Page 128: Zero to Mongo in 60 Hours

Day 200

• One production process

• One database

• Daily dumps using mongoexport + upload to S3

• Replication not running

• Several collections

Wednesday, April 28, 2010

Page 129: Zero to Mongo in 60 Hours

Day 200

• One production process

• One database

• Daily dumps using mongoexport + upload to S3

• Replication not running

• Several collections

• 100k to >10M documents

Wednesday, April 28, 2010

Page 130: Zero to Mongo in 60 Hours

Day 200

• One production process

• One database

• Daily dumps using mongoexport + upload to S3

• Replication not running

• Several collections

• 100k to >10M documents

• Scores of deep, composite indexes

Wednesday, April 28, 2010

Page 131: Zero to Mongo in 60 Hours

What tripped me up?

Wednesday, April 28, 2010

Page 132: Zero to Mongo in 60 Hours

Simple Test

should "get impressions_by_date" do

record1 = {:date => 100, :impression => 10}

record2 = {:date => 90, :impression => 8}

Mongo::Vendor.collection.insert record1

Mongo::Vendor.collection.insert record2

assert_same_elements [record1, record2],

Mongo::Vendor.impressions_by_date

end

Wednesday, April 28, 2010

Page 133: Zero to Mongo in 60 Hours

Crazy Failure

1) Failure:

test: Mongo::Vendor should get

impressions_by_date. (Mongo::VendorTest)

...

-<{{"date"=>100.0, "csum"=>10.0}=>1,

{"date"=>90.0, "csum"=>8.0}=>1}>

+<{{"date"=>90.0, "csum"=>8.0}=>1,

{"date"=>100.0, "csum"=>10.0}=>1}>

Wednesday, April 28, 2010

Page 134: Zero to Mongo in 60 Hours

Wednesday, April 28, 2010

Page 135: Zero to Mongo in 60 Hours

Mongo’s BSON OrderedHash doesn’t behave like ActiveSupport::OrderedHash

Wednesday, April 28, 2010

Page 136: Zero to Mongo in 60 Hours

irb(main):001:0> require 'active_support'irb(main):002:0> include ActiveSupportirb(main):003:0> oh = OrderedHash.newirb(main):004:0> oh[:b] = 2irb(main):005:0> oh[:c] = 3irb(main):006:0> oh[:a] = 1irb(main):007:0> a = {:a => 1, :b => 2, :c => 3}irb(main):008:0> a == oh=> trueirb(main):009:0> oh == a=> true

Mongo’s BSON OrderedHash doesn’t behave like ActiveSupport::OrderedHash

Wednesday, April 28, 2010

Page 137: Zero to Mongo in 60 Hours

irb(main):001:0> require 'active_support'irb(main):002:0> include ActiveSupportirb(main):003:0> oh = OrderedHash.newirb(main):004:0> oh[:b] = 2irb(main):005:0> oh[:c] = 3irb(main):006:0> oh[:a] = 1irb(main):007:0> a = {:a => 1, :b => 2, :c => 3}irb(main):008:0> a == oh=> trueirb(main):009:0> oh == a=> true

irb(main):001:0> require 'mongo'irb(main):002:0> oh = OrderedHash.newirb(main):003:0> oh[:b] = 2irb(main):004:0> oh[:c] = 3irb(main):005:0> oh[:a] = 1irb(main):006:0> a = {:a => 1, :b => 2, :c => 3}irb(main):007:0> a == oh=> true

Mongo’s BSON OrderedHash doesn’t behave like ActiveSupport::OrderedHash

Wednesday, April 28, 2010

Page 138: Zero to Mongo in 60 Hours

irb(main):001:0> require 'active_support'irb(main):002:0> include ActiveSupportirb(main):003:0> oh = OrderedHash.newirb(main):004:0> oh[:b] = 2irb(main):005:0> oh[:c] = 3irb(main):006:0> oh[:a] = 1irb(main):007:0> a = {:a => 1, :b => 2, :c => 3}irb(main):008:0> a == oh=> trueirb(main):009:0> oh == a=> true

irb(main):001:0> require 'mongo'irb(main):002:0> oh = OrderedHash.newirb(main):003:0> oh[:b] = 2irb(main):004:0> oh[:c] = 3irb(main):005:0> oh[:a] = 1irb(main):006:0> a = {:a => 1, :b => 2, :c => 3}irb(main):007:0> a == oh=> true

Mongo’s BSON OrderedHash doesn’t behave like ActiveSupport::OrderedHash

irb(main):008:0> oh == a=> false

Wednesday, April 28, 2010

Page 139: Zero to Mongo in 60 Hours

Wednesday, April 28, 2010

Page 140: Zero to Mongo in 60 Hours

And it turns out...

Wednesday, April 28, 2010

Page 141: Zero to Mongo in 60 Hours

And it turns out...

MongoDB will not add indexes to your collections.

Wednesday, April 28, 2010

Page 142: Zero to Mongo in 60 Hours

And it turns out...

MongoDB will not add indexes to your collections.

Unless you tell it to.

Wednesday, April 28, 2010

Page 143: Zero to Mongo in 60 Hours

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

add indexes

Wednesday, April 28, 2010

Page 144: Zero to Mongo in 60 Hours

But it’ll help pick up the pieces

Before index> db.vendors.findOne({'date': {'$gt': 1271895200}}){ ... }Sun Apr 25 01:19:51 query v_production.vendors ntoreturn:1 reslen:114 nscanned:~10M { date: { $gt: 1271895200.0 } } nreturned:1 3492ms

During index> db.vendors.ensureIndex({'date': 1}) Sun Apr 25 01:20:17 building new index on { date: 1.0 } for v_production.vendorsSun Apr 25 01:20:17 Buildindex v_production.vendors idxNo:2 { _id: ObjId(4bd398d1dbf523027368d566), ns: "v_production.vendors", key: { date: 1.0 }, name: "date_1" }! ! ...Sun Apr 25 01:21:35 ! done building bottom layer, going to commitSun Apr 25 01:21:35 done for ~10M records 78.56secsSun Apr 25 01:21:35 insert v_production.system.indexes 78560ms

After Index> db.vendors.find({'date': 1272153600}).explain(){! ...! "nscanned" : 11220,! "millis" : 12,! ...}

Wednesday, April 28, 2010

Page 145: Zero to Mongo in 60 Hours

But it’ll help pick up the pieces

Before index> db.vendors.findOne({'date': {'$gt': 1271895200}}){ ... }Sun Apr 25 01:19:51 query v_production.vendors ntoreturn:1 reslen:114 nscanned:~10M { date: { $gt: 1271895200.0 } } nreturned:1 3492ms

During index> db.vendors.ensureIndex({'date': 1}) Sun Apr 25 01:20:17 building new index on { date: 1.0 } for v_production.vendorsSun Apr 25 01:20:17 Buildindex v_production.vendors idxNo:2 { _id: ObjId(4bd398d1dbf523027368d566), ns: "v_production.vendors", key: { date: 1.0 }, name: "date_1" }! ! ...Sun Apr 25 01:21:35 ! done building bottom layer, going to commitSun Apr 25 01:21:35 done for ~10M records 78.56secsSun Apr 25 01:21:35 insert v_production.system.indexes 78560ms

After Index> db.vendors.find({'date': 1272153600}).explain(){! ...! "nscanned" : 11220,! "millis" : 12,! ...}

Full collection scan ~3.5s

Wednesday, April 28, 2010

Page 146: Zero to Mongo in 60 Hours

But it’ll help pick up the pieces

Before index> db.vendors.findOne({'date': {'$gt': 1271895200}}){ ... }Sun Apr 25 01:19:51 query v_production.vendors ntoreturn:1 reslen:114 nscanned:~10M { date: { $gt: 1271895200.0 } } nreturned:1 3492ms

During index> db.vendors.ensureIndex({'date': 1}) Sun Apr 25 01:20:17 building new index on { date: 1.0 } for v_production.vendorsSun Apr 25 01:20:17 Buildindex v_production.vendors idxNo:2 { _id: ObjId(4bd398d1dbf523027368d566), ns: "v_production.vendors", key: { date: 1.0 }, name: "date_1" }! ! ...Sun Apr 25 01:21:35 ! done building bottom layer, going to commitSun Apr 25 01:21:35 done for ~10M records 78.56secsSun Apr 25 01:21:35 insert v_production.system.indexes 78560ms

After Index> db.vendors.find({'date': 1272153600}).explain(){! ...! "nscanned" : 11220,! "millis" : 12,! ...}

Full collection scan ~3.5s

Index added ~79sNo locks.

Wednesday, April 28, 2010

Page 147: Zero to Mongo in 60 Hours

But it’ll help pick up the pieces

Before index> db.vendors.findOne({'date': {'$gt': 1271895200}}){ ... }Sun Apr 25 01:19:51 query v_production.vendors ntoreturn:1 reslen:114 nscanned:~10M { date: { $gt: 1271895200.0 } } nreturned:1 3492ms

During index> db.vendors.ensureIndex({'date': 1}) Sun Apr 25 01:20:17 building new index on { date: 1.0 } for v_production.vendorsSun Apr 25 01:20:17 Buildindex v_production.vendors idxNo:2 { _id: ObjId(4bd398d1dbf523027368d566), ns: "v_production.vendors", key: { date: 1.0 }, name: "date_1" }! ! ...Sun Apr 25 01:21:35 ! done building bottom layer, going to commitSun Apr 25 01:21:35 done for ~10M records 78.56secsSun Apr 25 01:21:35 insert v_production.system.indexes 78560ms

After Index> db.vendors.find({'date': 1272153600}).explain(){! ...! "nscanned" : 11220,! "millis" : 12,! ...}

Full collection scan ~3.5s

Index added ~79sNo locks.

12ms!

Wednesday, April 28, 2010

Page 148: Zero to Mongo in 60 Hours

But it’ll help pick up the pieces

Before index> db.vendors.findOne({'date': {'$gt': 1271895200}}){ ... }Sun Apr 25 01:19:51 query v_production.vendors ntoreturn:1 reslen:114 nscanned:~10M { date: { $gt: 1271895200.0 } } nreturned:1 3492ms

During index> db.vendors.ensureIndex({'date': 1}) Sun Apr 25 01:20:17 building new index on { date: 1.0 } for v_production.vendorsSun Apr 25 01:20:17 Buildindex v_production.vendors idxNo:2 { _id: ObjId(4bd398d1dbf523027368d566), ns: "v_production.vendors", key: { date: 1.0 }, name: "date_1" }! ! ...Sun Apr 25 01:21:35 ! done building bottom layer, going to commitSun Apr 25 01:21:35 done for ~10M records 78.56secsSun Apr 25 01:21:35 insert v_production.system.indexes 78560ms

After Index> db.vendors.find({'date': 1272153600}).explain(){! ...! "nscanned" : 11220,! "millis" : 12,! ...}

Full collection scan ~3.5s

Index added ~79sNo locks.

12ms!

During index creation, system completely CRUD responsive. No impact to

MyPunchbowl.com

Wednesday, April 28, 2010

Page 149: Zero to Mongo in 60 Hours

Up next: Top Secret Project

Wednesday, April 28, 2010

Page 150: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

Wednesday, April 28, 2010

Page 151: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

• SCREAMS for a document-based solution

Wednesday, April 28, 2010

Page 152: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

• SCREAMS for a document-based solution

• mongosphinx

• MongoDB’s ad-hoc full text search ok, lacks infix matching and bulk index building

• Geo-spatial search not yet ellipsoidal (or even spherical)

Wednesday, April 28, 2010

Page 153: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

• SCREAMS for a document-based solution

• mongosphinx

• MongoDB’s ad-hoc full text search ok, lacks infix matching and bulk index building

• Geo-spatial search not yet ellipsoidal (or even spherical)

• paperclip+mongomapper

Wednesday, April 28, 2010

Page 154: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

• SCREAMS for a document-based solution

• mongosphinx

• MongoDB’s ad-hoc full text search ok, lacks infix matching and bulk index building

• Geo-spatial search not yet ellipsoidal (or even spherical)

• paperclip+mongomapper

• MyPunchbowl user/event/invite data mining/visualization

Wednesday, April 28, 2010

Page 155: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

• SCREAMS for a document-based solution

• mongosphinx

• MongoDB’s ad-hoc full text search ok, lacks infix matching and bulk index building

• Geo-spatial search not yet ellipsoidal (or even spherical)

• paperclip+mongomapper

• MyPunchbowl user/event/invite data mining/visualization

• Charding + MapReduce = Nerdstorm

Wednesday, April 28, 2010

Page 156: Zero to Mongo in 60 Hours

Up next: Top Secret Project

• Project involving

• SCREAMS for a document-based solution

• mongosphinx

• MongoDB’s ad-hoc full text search ok, lacks infix matching and bulk index building

• Geo-spatial search not yet ellipsoidal (or even spherical)

• paperclip+mongomapper

• MyPunchbowl user/event/invite data mining/visualization

• Charding + MapReduce = Nerdstorm

• Building tools to speed up ETL out of MySQL and into MongoDB

Wednesday, April 28, 2010

Page 157: Zero to Mongo in 60 Hours

The end

Questions?

Wednesday, April 28, 2010

Page 158: Zero to Mongo in 60 Hours

Contact Me

[email protected]

http://www.mypunchbowl.com

http://ryanangilly.com

@angilly

Wednesday, April 28, 2010

Page 159: Zero to Mongo in 60 Hours

Links

Slide 3/4 logos, wget’d from all over the Internets.

Dunce Cap http://steynian.files.wordpress.com/2009/09/dunce-cap.jpg

http://railstips.org/blog/archives/2009/12/18/why-i-think-mongo-is-to-databases-what-rails-was-to-frameworks/

http://railstips.org/blog/archives/2009/11/10/config-so-simple-your-mama-could-use-it/

Vendors configuration http://gist.github.com/380213

Wednesday, April 28, 2010