SlideShare a Scribd company logo
1 of 49
RedDotRubyConf 2011



Benefits of MongoDB:
  Reduce Complexity &
   Adapt to Changes

       Vinova Pte Ltd
About me
• Alex Nguyen
• Co-founder at Vinova
• http://vinova.sg/
• https://github.com/vinova/
Agenda

• What’s MongoDB?
•   Why MongoDB reduce complexity?

•   Why MongoDB adapt to changes better?

• Case studies
I don’t hate SQL

Just found a better tool
  for most of my use
         cases
What’s MongoDB?

   “MongoDB (from "humongous") is a scalable, high-
    performance, open source, document-oriented
                     database”




mongodb.org
What’s MongoDB?




http://www.slideshare.net/kbanker/mongodb-schema-design-mongo-chicago
What’s MongoDB?


• Collections ~ Tables
• Documents ~ Rows
MongoDB Philosophy
     • Reduce transactional semantics for
       performance
     • No-relational is the best way to scale
       horizontally




mongodb.org
MongoDB Features

• JSON style documents     • Map / Reduce
• Index on any attribute   • GridFS to store files
• Rich queries             • Server-side JavaScript
• In-place update          • Capped collections
• Auto-sharding            • Full-text-search
                             (coming soon)
MongoDB's flexibility data structure, ability to index &
query data, and auto-sharding make it a strong tool that
adapt to changes well. It also help to reduce complexity
            comparing to tradition RDBMS.
Why MongoDB reduce
    complexity?
• Get rid of migrations
• Get rid of relationships (most of)
• Reduce number of database requests
• JSON (client, server, and database)
Get rid of migrations

• No create table
• No alter column
• No add column
• No change column
Get rid of relationships

• Many one-to-one and one-to-many
  relationships is not necessary
 • User :has_one :setting
 • User :has_many :addresses
 • User :has_many :roles
 • Post :has_many :tags
Reduce number of
   database requests

• Pre-joined
• Rich queries
• Atomic, in-place updates
JSON


• MongoDB knows JSON
• Don’t have to convert data from / to JSON
Adapt to changes

• Changes in schema
• Changes in data & algorithms
• Changes for performance & scaling
Changes in schema

• In modern apps, schema changes quite
  often (weekly, monthly ...)
• Alter tables are expensive in RDBMS
• Dynamic schema document makes those
  changes seamlessly
Changes in data &
     algorithms
• Atomic, in-place updates are very
   powerful to modify data
   $inc, $set, $unset, $push, $pop, $rename, $bit

• Rich$all, $exists,and aggregators
  $in,
       queries
                     $size, $type, regexp
   count(), size(), distinct(), min(), max()

• Map/Reduce
Changes for
performance & scaling

• Very fast & ready to scale =>
 • Don’t have to use additional tools
    (memcached ...)
 • Don’t have to change platforms
Case Studies

• Store crawled info as embedded documents
• Product listing
• Find unique slug
• Voting
Store crawled info as
embedded documents

• Data from 3rd party sources
• Sources and data formats can be changed in
  the future
Store crawled info as
embedded documents
 product = {
    "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
    "name" : "Product ABC",
    "amazon" : {
      "asin" : ...,
      "price" : ...,
      ....
    }
 };
Store crawled info as
embedded documents
 product = {
    "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
    "name" : "Product ABC",
    "amazon" : {
      "asin" : ...,
      "price" : ...,
      "shipping_cost" : ...,
      ...
    }
 };
Store crawled info as
embedded documents
 product = {
    "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
    "name" : "Product ABC",
    "amazon" : {
       "asin" : ...,
       "price" : ...,
       "shipping_cost" : ...,
       ....
    },
    "walmart" : {
       "price" : ...,
       ...
    }
 };
Store crawled info as
embedded documents

  def Product.find_by_asin(asin)
    Product.where('amazon.asin' => asin).first
  end
Product listing

• A product can be listed on multiple
  categories on certain months
Product listing
• Need an extra table to express which
  product is listed in which category and
  on which month




  product_id category_id   month
      1           2        2011-03
      1           2        2011-04
                                            SQL
Product listing
 • To query products listed in category 2 and
     month ‘2011-04’
Product.join(:listings).where('category_id = ? AND month = ?', 2,
‘2011-04’)




                                                         SQL
Product listing
 • Store listings in product itself
product = {
   "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
   "name" : "Product ABC",
   "listings" : [ [1, "2011-01"], [1, "2011-04"], [3,
"2011-01"] ]
};




                                                        Mongo
Product listing
 • Store listings in product itself
product = {
   "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
   "name" : "Product ABC",
   "listings" : [ [1, "2011-01"], [1, "2011-04"], [3,
"2011-01"] ]
};


  • Query is simpler
Product.where("listings" => [1, '2011-04'])




                                                        Mongo
Product listing
 • Store listings in product itself
product = {
   "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
   "name" : "Product ABC",
   "listings" : [ [1, "2011-01"], [1, "2011-04"], [3,
"2011-01"] ]
};


  • Query is simpler
Product.where("listings" => [1, '2011-04'])



  • Can index listings array
db.products.ensureIndex({"listings" : 1 });
                                                        Mongo
Product listing
 • Clearer but more data storage
product = {
   "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
   "name" : "Product ABC",
   "listings" : [
     {"category_id" : 1, "month" : "2011-01" }, {"category_id" : 1,
"month" : "2011-04" }, {"category_id" : 3, "month" : "2011-01" }]
};

db.products.find("listings" : {"category_id" : 1, "month" :
"2011-04" })




                                                    Mongo
Find unique slug
 • book1 = #<Book id: .., title => “Ruby”, ... >
 • book2 = #<Book id: .., title => “Ruby”, ... >
 • book2.uniq_slug => /books/ruby-1
 • Need n queries to find an unique slug
def uniq_slug
  slug = original_slug = title.to_slug
  counter = 0
  while (where(:slug => slug).count > 0)
    counter += 1
    slug = "#{original_slug}-#{counter}"
  end
  slug
end                                           SQL
Find unique slug
 • Need one query using regexp matching
def find_uniq_slug
  original_slug = title.to_slug
  slug_pattern = /^#{original_slug}(-d+)?$/
  book = where(:slug => slug_pattern).
           order(:slug.desc).limit(1)
  if book
    max_counter = book.slug.match(/-(d+)$/)[1].to_i
    "#{original_slug}-#{max_counter + 1}"
  else
    original_slug
  end
end

db.books.ensureIndex({"slug" : -1 })

                                                       Mongo
Voting
• A user can only vote each post once
• up / down votes has different points
• Cached votes_count and votes_point in
  post for sorting and querying
 •   Post.max(:votes_point)

 •   Post.order_by(:votes_count.desc)
Voting
• Use extra votes table to store vote data




                                             SQL
Voting
def vote(user_id, post_id, value)
  # Validate
  not_voted = Vote.where(:user_id => user_id,
    :post_id => post_id).count == 0
  if not_voted
    # Create a new vote
    Vote.create(
      :user_id => user_id,
      :post_id => post_id,
      :value => value
    )
    # Get post
    post = Post.find(post_id)
    # Update votes_point & votes_count
    post.votes_point += POINT[value]
    post.votes_count += 1
    post.save
  end
end                                             SQL
Voting
def vote(user_id, post_id, value)
  # Validate
  not_voted = Vote.where(:user_id => user_id,
    :post_id => post_id).count == 0
  if not_voted
    # Create a new vote
    Vote.create(
      :user_id => user_id,                      4 requests
      :post_id => post_id,
      :value => value
    )
    # Get post
    post = Post.find(post_id)
    # Update votes_point & votes_count
    post.votes_point += POINT[value]
    post.votes_count += 1
    post.save
  end
end                                                 SQL
Voting
def unvote(user_id, post_id)
  # Get current vote
  vote = Vote.where(:user_id => user_id,
    :post_id => post_id).first

  # Check if voted
  if vote
    # Destroy vote
    vote.destroy

    # Get post
    post = Post.find(post_id)

    # Update votes_point & votes_count
    post.votes_point -= POINT[vote.value]
    post.votes_count -= 1
    post.save
  end
end                                         SQL
Voting
def unvote(user_id, post_id)
  # Get current vote
  vote = Vote.where(:user_id => user_id,
    :post_id => post_id).first

  # Check if voted
  if vote
    # Destroy vote                          4 requests
    vote.destroy

    # Get post
    post = Post.find(post_id)

    # Update votes_point & votes_count
    post.votes_point -= POINT[vote.value]
    post.votes_count -= 1
    post.save
  end
end                                             SQL
Voting
 • Embed votes data to post
 • use arrays to store who vote up and who
    vote down
post = {
   "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"),
   "title" : "Post ABC",
   ....
   "votes" : {
     "up" : [ user_id_1 ],
     "down" : [ user_id_2 ],
     "count" => 2,
     "point" => -1


                                                   Mongo
   }
};
def vote(user_id, post_id, value)
  # Find post with post_id that was not up voted or down voted by user_id
  query = {
    'post_id' => post_id,
    'votes.up' => { '$ne' => user_id },
    'votes.down' => { '$ne' => user_id }
  }

 # Push user_id to votes.up_ids if vote up or votes.down_ids if vote_down
 # and update votes.point and votes.count
 update = {
   '$push' => {
      (value == :up ? 'votes.up' : 'votes.down') => user_id
   },
   '$inc' => {
      'votes.point' => POINT[value],
      'votes.count' => +1
   }
 }

  # Validate, update and get result
  post = Post.collection.find_and_modify(
    :query => query,
    :update => update,
    :new => true # return post after update votes data
  )
end                                                               Mongo
def vote(user_id, post_id, value)
  # Find post with post_id that was not up voted or down voted by user_id
  query = {
    'post_id' => post_id,
    'votes.up' => { '$ne' => user_id },
    'votes.down' => { '$ne' => user_id }
  }

 # Push user_id to votes.up_ids if vote up or votes.down_ids if vote_down
 # and update votes.point and votes.count
 update = {
   '$push' => {
      (value == :up ? 'votes.up' : 'votes.down') => user_id
   },
   '$inc' => {
      'votes.point' => POINT[value],
      'votes.count' => +1
   }
 }

  # Validate, update and get result
  post = Post.collection.find_and_modify(
    :query => query,                                              one request
    :update => update,
    :new => true # return post after update votes data
  )
end                                                               Mongo
def unvote(user_id, post_id)
  # Find post with post_id that was up voted or down voted by user_id
  query = {
    'post_id' => post_id,
    '$or' => { 'votes.up' => user_id, 'votes.down' => user_id }
  }

 # Pull user_id from both votes.up_ids and votes.down_ids
 # and update votes.point and votes.count
 update = {
   '$pull' => {
      'votes.up' => user_id,
      'votes.down' => user_id
   },
   '$inc' => {
      'votes.point' => -POINT[value],
      'votes.count' => -1
   }
 }

  # Validate, update and get result
  post = Post.collection.find_and_modify(
    :query => query,
    :update => update,
    :new => true # return post after update votes data
  )
end                                                               Mongo
def unvote(user_id, post_id)
  # Find post with post_id that was up voted or down voted by user_id
  query = {
    'post_id' => post_id,
    '$or' => { 'votes.up' => user_id, 'votes.down' => user_id }
  }

 # Pull user_id from both votes.up_ids and votes.down_ids
 # and update votes.point and votes.count
 update = {
   '$pull' => {
      'votes.up' => user_id,
      'votes.down' => user_id
   },
   '$inc' => {
      'votes.point' => -POINT[value],
      'votes.count' => -1
   }
 }

  # Validate, update and get result
  post = Post.collection.find_and_modify(
    :query => query,                                              one request
    :update => update,
    :new => true # return post after update votes data
  )
end                                                               Mongo
Voting

• For a complete solution:
• gem install voteable_mongoid
• visit https://github.com/vinova/voteable_mongoid
Summary

• MongoDB is
 • Flexible
 • Powerful
 • Fun
Thank you

 Alex Nguyen
 @tiendung
alex@vinova.sg
References
Introduction to MongoDB
 • http://scribd.com/doc/26506063/Introduction-To-MongoDB
 • http://slideshare.net/jnunemaker/why-mongodb-is-awesome

Schema Design
 • http://slideshare.net/kbanker/mongodb-schema-design-mongo-chicago

Indexing & Query Optimization
 • http://slideshare.net/mongodb/indexing-with-mongodb
 • http://slideshare.net/mongodb/mongodb-indexing-the-details

More Related Content

What's hot

Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBJustin Smestad
 
MongoDB Schema Design by Examples
MongoDB Schema Design by ExamplesMongoDB Schema Design by Examples
MongoDB Schema Design by ExamplesHadi Ariawan
 
OSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB TutorialOSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB TutorialSteven Francia
 
Conceptos básicos. Seminario web 6: Despliegue de producción
Conceptos básicos. Seminario web 6: Despliegue de producciónConceptos básicos. Seminario web 6: Despliegue de producción
Conceptos básicos. Seminario web 6: Despliegue de producciónMongoDB
 
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
 
MongoDB : The Definitive Guide
MongoDB : The Definitive GuideMongoDB : The Definitive Guide
MongoDB : The Definitive GuideWildan Maulana
 
MongoDB basics & Introduction
MongoDB basics & IntroductionMongoDB basics & Introduction
MongoDB basics & IntroductionJerwin Roy
 
Connecting NodeJS & MongoDB
Connecting NodeJS & MongoDBConnecting NodeJS & MongoDB
Connecting NodeJS & MongoDBEnoch Joshua
 
Agility and Scalability with MongoDB
Agility and Scalability with MongoDBAgility and Scalability with MongoDB
Agility and Scalability with MongoDBMongoDB
 
Practical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo DbPractical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo DbAlex Sharp
 
mongoDB Performance
mongoDB PerformancemongoDB Performance
mongoDB PerformanceMoshe Kaplan
 
An Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDBAn Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDBLee Theobald
 

What's hot (20)

Mongo db
Mongo dbMongo db
Mongo db
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
MongoDB Schema Design by Examples
MongoDB Schema Design by ExamplesMongoDB Schema Design by Examples
MongoDB Schema Design by Examples
 
Introduction to mongo db
Introduction to mongo dbIntroduction to mongo db
Introduction to mongo db
 
MongoDB
MongoDBMongoDB
MongoDB
 
OSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB TutorialOSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB Tutorial
 
Conceptos básicos. Seminario web 6: Despliegue de producción
Conceptos básicos. Seminario web 6: Despliegue de producciónConceptos básicos. Seminario web 6: Despliegue de producción
Conceptos básicos. Seminario web 6: Despliegue de producción
 
Mongo db dhruba
Mongo db dhrubaMongo db dhruba
Mongo db dhruba
 
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)
 
MongoDB : The Definitive Guide
MongoDB : The Definitive GuideMongoDB : The Definitive Guide
MongoDB : The Definitive Guide
 
MongoDB and Schema Design
MongoDB and Schema DesignMongoDB and Schema Design
MongoDB and Schema Design
 
MongoDB basics & Introduction
MongoDB basics & IntroductionMongoDB basics & Introduction
MongoDB basics & Introduction
 
Connecting NodeJS & MongoDB
Connecting NodeJS & MongoDBConnecting NodeJS & MongoDB
Connecting NodeJS & MongoDB
 
No sql
No sqlNo sql
No sql
 
Agility and Scalability with MongoDB
Agility and Scalability with MongoDBAgility and Scalability with MongoDB
Agility and Scalability with MongoDB
 
Mongo db
Mongo dbMongo db
Mongo db
 
Practical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo DbPractical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo Db
 
Mongo db
Mongo dbMongo db
Mongo db
 
mongoDB Performance
mongoDB PerformancemongoDB Performance
mongoDB Performance
 
An Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDBAn Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDB
 

Similar to Benefits of using MongoDB: Reduce Complexity & Adapt to Changes

Schema Design with MongoDB
Schema Design with MongoDBSchema Design with MongoDB
Schema Design with MongoDBrogerbodamer
 
10gen Presents Schema Design and Data Modeling
10gen Presents Schema Design and Data Modeling10gen Presents Schema Design and Data Modeling
10gen Presents Schema Design and Data ModelingDATAVERSITY
 
Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling rogerbodamer
 
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'tsThe Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'tsMatias Cascallares
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDCMike Dirolf
 
Building Apps with MongoDB
Building Apps with MongoDBBuilding Apps with MongoDB
Building Apps with MongoDBNate Abele
 
MongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: Tutorial
MongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: TutorialMongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: Tutorial
MongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: TutorialMongoDB
 
PostgreSQLからMongoDBへ
PostgreSQLからMongoDBへPostgreSQLからMongoDBへ
PostgreSQLからMongoDBへBasuke Suzuki
 
Schema Design (Mongo Austin)
Schema Design (Mongo Austin)Schema Design (Mongo Austin)
Schema Design (Mongo Austin)MongoDB
 
Advanced Document Modeling Techniques from a High-Scale Commerce Platform
Advanced Document Modeling Techniques from a High-Scale Commerce PlatformAdvanced Document Modeling Techniques from a High-Scale Commerce Platform
Advanced Document Modeling Techniques from a High-Scale Commerce PlatformMongoDB
 
Indexing Strategies to Help You Scale
Indexing Strategies to Help You ScaleIndexing Strategies to Help You Scale
Indexing Strategies to Help You ScaleMongoDB
 
OSDC 2012 | Building a first application on MongoDB by Ross Lawley
OSDC 2012 | Building a first application on MongoDB by Ross LawleyOSDC 2012 | Building a first application on MongoDB by Ross Lawley
OSDC 2012 | Building a first application on MongoDB by Ross LawleyNETWAYS
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDBMongoDB
 
Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19
Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19
Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19Henrik Ingo
 
Elasticsearch an overview
Elasticsearch   an overviewElasticsearch   an overview
Elasticsearch an overviewAmit Juneja
 
Mongodb intro
Mongodb introMongodb intro
Mongodb introchristkv
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBMongoDB
 
Web осень 2012 лекция 6
Web осень 2012 лекция 6Web осень 2012 лекция 6
Web осень 2012 лекция 6Technopark
 

Similar to Benefits of using MongoDB: Reduce Complexity & Adapt to Changes (20)

Schema Design with MongoDB
Schema Design with MongoDBSchema Design with MongoDB
Schema Design with MongoDB
 
10gen Presents Schema Design and Data Modeling
10gen Presents Schema Design and Data Modeling10gen Presents Schema Design and Data Modeling
10gen Presents Schema Design and Data Modeling
 
Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling
 
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'tsThe Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
 
Introduction to RavenDB
Introduction to RavenDBIntroduction to RavenDB
Introduction to RavenDB
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
 
Building Apps with MongoDB
Building Apps with MongoDBBuilding Apps with MongoDB
Building Apps with MongoDB
 
MongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: Tutorial
MongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: TutorialMongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: Tutorial
MongoDB .local Chicago 2019: Practical Data Modeling for MongoDB: Tutorial
 
PostgreSQLからMongoDBへ
PostgreSQLからMongoDBへPostgreSQLからMongoDBへ
PostgreSQLからMongoDBへ
 
Schema Design (Mongo Austin)
Schema Design (Mongo Austin)Schema Design (Mongo Austin)
Schema Design (Mongo Austin)
 
Advanced Document Modeling Techniques from a High-Scale Commerce Platform
Advanced Document Modeling Techniques from a High-Scale Commerce PlatformAdvanced Document Modeling Techniques from a High-Scale Commerce Platform
Advanced Document Modeling Techniques from a High-Scale Commerce Platform
 
Indexing Strategies to Help You Scale
Indexing Strategies to Help You ScaleIndexing Strategies to Help You Scale
Indexing Strategies to Help You Scale
 
OSDC 2012 | Building a first application on MongoDB by Ross Lawley
OSDC 2012 | Building a first application on MongoDB by Ross LawleyOSDC 2012 | Building a first application on MongoDB by Ross Lawley
OSDC 2012 | Building a first application on MongoDB by Ross Lawley
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDB
 
Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19
Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19
Whats new in mongoDB 2.4 at Copenhagen user group 2013-06-19
 
Elasticsearch an overview
Elasticsearch   an overviewElasticsearch   an overview
Elasticsearch an overview
 
Mongodb intro
Mongodb introMongodb intro
Mongodb intro
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
 
Elasticsearch
ElasticsearchElasticsearch
Elasticsearch
 
Web осень 2012 лекция 6
Web осень 2012 лекция 6Web осень 2012 лекция 6
Web осень 2012 лекция 6
 

Recently uploaded

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
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
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
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
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
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
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
 
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
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
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
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
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
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"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
 
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
 

Recently uploaded (20)

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
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
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
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
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
 
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!
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
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
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
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
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"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
 
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
 

Benefits of using MongoDB: Reduce Complexity & Adapt to Changes

  • 1. RedDotRubyConf 2011 Benefits of MongoDB: Reduce Complexity & Adapt to Changes Vinova Pte Ltd
  • 2. About me • Alex Nguyen • Co-founder at Vinova • http://vinova.sg/ • https://github.com/vinova/
  • 3. Agenda • What’s MongoDB? • Why MongoDB reduce complexity? • Why MongoDB adapt to changes better? • Case studies
  • 4. I don’t hate SQL Just found a better tool for most of my use cases
  • 5. What’s MongoDB? “MongoDB (from "humongous") is a scalable, high- performance, open source, document-oriented database” mongodb.org
  • 7. What’s MongoDB? • Collections ~ Tables • Documents ~ Rows
  • 8. MongoDB Philosophy • Reduce transactional semantics for performance • No-relational is the best way to scale horizontally mongodb.org
  • 9. MongoDB Features • JSON style documents • Map / Reduce • Index on any attribute • GridFS to store files • Rich queries • Server-side JavaScript • In-place update • Capped collections • Auto-sharding • Full-text-search (coming soon)
  • 10. MongoDB's flexibility data structure, ability to index & query data, and auto-sharding make it a strong tool that adapt to changes well. It also help to reduce complexity comparing to tradition RDBMS.
  • 11. Why MongoDB reduce complexity? • Get rid of migrations • Get rid of relationships (most of) • Reduce number of database requests • JSON (client, server, and database)
  • 12. Get rid of migrations • No create table • No alter column • No add column • No change column
  • 13. Get rid of relationships • Many one-to-one and one-to-many relationships is not necessary • User :has_one :setting • User :has_many :addresses • User :has_many :roles • Post :has_many :tags
  • 14. Reduce number of database requests • Pre-joined • Rich queries • Atomic, in-place updates
  • 15. JSON • MongoDB knows JSON • Don’t have to convert data from / to JSON
  • 16. Adapt to changes • Changes in schema • Changes in data & algorithms • Changes for performance & scaling
  • 17. Changes in schema • In modern apps, schema changes quite often (weekly, monthly ...) • Alter tables are expensive in RDBMS • Dynamic schema document makes those changes seamlessly
  • 18. Changes in data & algorithms • Atomic, in-place updates are very powerful to modify data $inc, $set, $unset, $push, $pop, $rename, $bit • Rich$all, $exists,and aggregators $in, queries $size, $type, regexp count(), size(), distinct(), min(), max() • Map/Reduce
  • 19. Changes for performance & scaling • Very fast & ready to scale => • Don’t have to use additional tools (memcached ...) • Don’t have to change platforms
  • 20. Case Studies • Store crawled info as embedded documents • Product listing • Find unique slug • Voting
  • 21. Store crawled info as embedded documents • Data from 3rd party sources • Sources and data formats can be changed in the future
  • 22. Store crawled info as embedded documents product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "amazon" : { "asin" : ..., "price" : ..., .... } };
  • 23. Store crawled info as embedded documents product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "amazon" : { "asin" : ..., "price" : ..., "shipping_cost" : ..., ... } };
  • 24. Store crawled info as embedded documents product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "amazon" : { "asin" : ..., "price" : ..., "shipping_cost" : ..., .... }, "walmart" : { "price" : ..., ... } };
  • 25. Store crawled info as embedded documents def Product.find_by_asin(asin) Product.where('amazon.asin' => asin).first end
  • 26. Product listing • A product can be listed on multiple categories on certain months
  • 27. Product listing • Need an extra table to express which product is listed in which category and on which month product_id category_id month 1 2 2011-03 1 2 2011-04 SQL
  • 28. Product listing • To query products listed in category 2 and month ‘2011-04’ Product.join(:listings).where('category_id = ? AND month = ?', 2, ‘2011-04’) SQL
  • 29. Product listing • Store listings in product itself product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "listings" : [ [1, "2011-01"], [1, "2011-04"], [3, "2011-01"] ] }; Mongo
  • 30. Product listing • Store listings in product itself product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "listings" : [ [1, "2011-01"], [1, "2011-04"], [3, "2011-01"] ] }; • Query is simpler Product.where("listings" => [1, '2011-04']) Mongo
  • 31. Product listing • Store listings in product itself product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "listings" : [ [1, "2011-01"], [1, "2011-04"], [3, "2011-01"] ] }; • Query is simpler Product.where("listings" => [1, '2011-04']) • Can index listings array db.products.ensureIndex({"listings" : 1 }); Mongo
  • 32. Product listing • Clearer but more data storage product = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "name" : "Product ABC", "listings" : [ {"category_id" : 1, "month" : "2011-01" }, {"category_id" : 1, "month" : "2011-04" }, {"category_id" : 3, "month" : "2011-01" }] }; db.products.find("listings" : {"category_id" : 1, "month" : "2011-04" }) Mongo
  • 33. Find unique slug • book1 = #<Book id: .., title => “Ruby”, ... > • book2 = #<Book id: .., title => “Ruby”, ... > • book2.uniq_slug => /books/ruby-1 • Need n queries to find an unique slug def uniq_slug slug = original_slug = title.to_slug counter = 0 while (where(:slug => slug).count > 0) counter += 1 slug = "#{original_slug}-#{counter}" end slug end SQL
  • 34. Find unique slug • Need one query using regexp matching def find_uniq_slug original_slug = title.to_slug slug_pattern = /^#{original_slug}(-d+)?$/ book = where(:slug => slug_pattern). order(:slug.desc).limit(1) if book max_counter = book.slug.match(/-(d+)$/)[1].to_i "#{original_slug}-#{max_counter + 1}" else original_slug end end db.books.ensureIndex({"slug" : -1 }) Mongo
  • 35. Voting • A user can only vote each post once • up / down votes has different points • Cached votes_count and votes_point in post for sorting and querying • Post.max(:votes_point) • Post.order_by(:votes_count.desc)
  • 36. Voting • Use extra votes table to store vote data SQL
  • 37. Voting def vote(user_id, post_id, value) # Validate not_voted = Vote.where(:user_id => user_id, :post_id => post_id).count == 0 if not_voted # Create a new vote Vote.create( :user_id => user_id, :post_id => post_id, :value => value ) # Get post post = Post.find(post_id) # Update votes_point & votes_count post.votes_point += POINT[value] post.votes_count += 1 post.save end end SQL
  • 38. Voting def vote(user_id, post_id, value) # Validate not_voted = Vote.where(:user_id => user_id, :post_id => post_id).count == 0 if not_voted # Create a new vote Vote.create( :user_id => user_id, 4 requests :post_id => post_id, :value => value ) # Get post post = Post.find(post_id) # Update votes_point & votes_count post.votes_point += POINT[value] post.votes_count += 1 post.save end end SQL
  • 39. Voting def unvote(user_id, post_id) # Get current vote vote = Vote.where(:user_id => user_id, :post_id => post_id).first # Check if voted if vote # Destroy vote vote.destroy # Get post post = Post.find(post_id) # Update votes_point & votes_count post.votes_point -= POINT[vote.value] post.votes_count -= 1 post.save end end SQL
  • 40. Voting def unvote(user_id, post_id) # Get current vote vote = Vote.where(:user_id => user_id, :post_id => post_id).first # Check if voted if vote # Destroy vote 4 requests vote.destroy # Get post post = Post.find(post_id) # Update votes_point & votes_count post.votes_point -= POINT[vote.value] post.votes_count -= 1 post.save end end SQL
  • 41. Voting • Embed votes data to post • use arrays to store who vote up and who vote down post = { "_id" : ObjectId("4d8ace4b0dc3e43231bb930d"), "title" : "Post ABC", .... "votes" : { "up" : [ user_id_1 ], "down" : [ user_id_2 ], "count" => 2, "point" => -1 Mongo } };
  • 42. def vote(user_id, post_id, value) # Find post with post_id that was not up voted or down voted by user_id query = { 'post_id' => post_id, 'votes.up' => { '$ne' => user_id }, 'votes.down' => { '$ne' => user_id } } # Push user_id to votes.up_ids if vote up or votes.down_ids if vote_down # and update votes.point and votes.count update = { '$push' => { (value == :up ? 'votes.up' : 'votes.down') => user_id }, '$inc' => { 'votes.point' => POINT[value], 'votes.count' => +1 } } # Validate, update and get result post = Post.collection.find_and_modify( :query => query, :update => update, :new => true # return post after update votes data ) end Mongo
  • 43. def vote(user_id, post_id, value) # Find post with post_id that was not up voted or down voted by user_id query = { 'post_id' => post_id, 'votes.up' => { '$ne' => user_id }, 'votes.down' => { '$ne' => user_id } } # Push user_id to votes.up_ids if vote up or votes.down_ids if vote_down # and update votes.point and votes.count update = { '$push' => { (value == :up ? 'votes.up' : 'votes.down') => user_id }, '$inc' => { 'votes.point' => POINT[value], 'votes.count' => +1 } } # Validate, update and get result post = Post.collection.find_and_modify( :query => query, one request :update => update, :new => true # return post after update votes data ) end Mongo
  • 44. def unvote(user_id, post_id) # Find post with post_id that was up voted or down voted by user_id query = { 'post_id' => post_id, '$or' => { 'votes.up' => user_id, 'votes.down' => user_id } } # Pull user_id from both votes.up_ids and votes.down_ids # and update votes.point and votes.count update = { '$pull' => { 'votes.up' => user_id, 'votes.down' => user_id }, '$inc' => { 'votes.point' => -POINT[value], 'votes.count' => -1 } } # Validate, update and get result post = Post.collection.find_and_modify( :query => query, :update => update, :new => true # return post after update votes data ) end Mongo
  • 45. def unvote(user_id, post_id) # Find post with post_id that was up voted or down voted by user_id query = { 'post_id' => post_id, '$or' => { 'votes.up' => user_id, 'votes.down' => user_id } } # Pull user_id from both votes.up_ids and votes.down_ids # and update votes.point and votes.count update = { '$pull' => { 'votes.up' => user_id, 'votes.down' => user_id }, '$inc' => { 'votes.point' => -POINT[value], 'votes.count' => -1 } } # Validate, update and get result post = Post.collection.find_and_modify( :query => query, one request :update => update, :new => true # return post after update votes data ) end Mongo
  • 46. Voting • For a complete solution: • gem install voteable_mongoid • visit https://github.com/vinova/voteable_mongoid
  • 47. Summary • MongoDB is • Flexible • Powerful • Fun
  • 48. Thank you Alex Nguyen @tiendung alex@vinova.sg
  • 49. References Introduction to MongoDB • http://scribd.com/doc/26506063/Introduction-To-MongoDB • http://slideshare.net/jnunemaker/why-mongodb-is-awesome Schema Design • http://slideshare.net/kbanker/mongodb-schema-design-mongo-chicago Indexing & Query Optimization • http://slideshare.net/mongodb/indexing-with-mongodb • http://slideshare.net/mongodb/mongodb-indexing-the-details

Editor's Notes

  1. Hi everyone. It&amp;#x2019;s my pleasure to be here today. I&amp;#x2019;m going to talk about MongoDB one of the most popular NoSQL databases.\n
  2. Hi, my name is Alex. I&amp;#x2019;m co-founder at Vinova. We are a Ruby on Rails and Mobile App development shop in Singapore. We&amp;#x2019;ve doing Rails for 5 years.\n\nWe are growing and looking for projects. If you need expertise&apos;s, feel free to contact us.\n
  3. \n
  4. I love SQL. I&amp;#x2019;ve done a lot of projects using MySQL, PostgreSQL ... \nI just found a better tool\n
  5. What&amp;#x2019;s MongoDB. MongoDB is a open source, document-oriented database that want to be the best database for web apps (not everything)\n
  6. Document-oriented is like this. \n\nThink of document as a Hash in Ruby or an Object in JavaScript.\n\nYou can store anything in document. Id, string, number, array and other documents (embedded documents).\n\n
  7. In relational database, we have tables and rows. In MongoDB we have collections and documents. You can think of collections as tables and documents as rows.\n
  8. MongoDB try to be as fast and scalable as key / value stores without loosing functionality.\n
  9. MongoDB has a lot of great features. Rich query interface, atomic and in-place update\n
  10. My experiences show that ..\n
  11. Why mongo reduce complexity?\n
  12. Because by using MongoDB we can get rid of migrations\n
  13. Get rid of relationships. \n\nFor data don&amp;#x2019;t share among objects or small enough. We just store it as a nested documents or arrays. So many 1-1 and 1-n relationships is not really necessary.\n
  14. MongoDB help to reduce number of database requests because we already pre-joined your data by storing 1-1, 1-n relational data as arrays or nested document.\n
  15. Because Mongo know JSON we don&amp;#x2019;t have to convert data to JSON format.\nWe can pull JSON from Mongo and push it to client as it is.\n\n
  16. \n
  17. \n
  18. Atomic, in-place updates are very powerful to modify data. I&amp;#x2019;ll show you in one of the case-studies later.\n\n
  19. Feed enough hardware resources to MongoDB to keep it run fast. \nWhen you need to scale your DB to multiple boxes you just do it.\n\nUnless your target is to build next Google or Facebook you may need Hadoop, HBase, Hive or Cassandra. For most use-cases, I think MongoDB is GOOD enough for scaling.\n
  20. \n
  21. A common use-cases I met is storing crawled information from various third party websites. Later we want to add more sources and they may change the data format in the future.\n
  22. Normally, when using SQL I have to create an additional table for each source. For MongoDB, I just push them the object itself as an embedded document like this.\n
  23. Then later, any changes in data structure like adding a new field\n
  24. or adding new source, I just push it to the product object. No migration, now new table creating\n
  25. And I can query those information use later using dot notation.\n
  26. Another problem that can utilize both MongoDB document and ability to index everything is product listing.\n\nI built an online catalogue application to show products, and a product can be listed on multiple category on certain months\n
  27. In SQL I need an extra table to express which product is listed in which category and on which month.\n\nListings table is not really a join table, since product_id and category_id can be duplicated.\n
  28. To query product listed on a specific category and month. I need to join products table with listing table and do the query.\n
  29. When using MongoDB we don&amp;#x2019;t need listings table. We store listings as an array of value pair [category_id, month]\n
  30. \n
  31. Can index listings array so speed up query\n
  32. Instead of category_id, month pair we can store listings as an arrays of object that people know which value is category id, which value is month explicitly. But it require more storage to store field names.\n\nI don&amp;#x2019;t recommend that for simple data structure like listings.\n
  33. Another example that show the power Mongo query is finding uniq slug.\n\nWe have many books with the same title &amp;#x201C;Ruby&amp;#x201D; but different categories.\n\nIn SQL we need n queries to find uniq slug for each of them. \n\nThe algorithm is simple, init slug from book&amp;#x2019;s title, set counter to zero. Check if slug is already in use, if yes increase the counter, modify slug and continue until we found an unique one.\n
  34. In Mongo, we don&amp;#x2019;t have to write the while loop by using regular expression matching.\n\nFirst we init the original slug and slug pattern that match the original slug and it variants.\n\nUse regular expression matching to find the variant with max counter value.\n\nIf found, extract the max counter value, increase it by one to create the uniq slug.\n\nIf original slug and it&amp;#x2019;s variants are not in used. Return the original slug.\n\nAnd don&amp;#x2019;t forget to index slug field to speed up your query.\n
  35. The last case study is voting. By solving this problem in both SQL and Mongo, I will show you how flexible and powerful Mongo is to avoid join table reduce number of database requests.\n\nThe problem is like this. In a forum, a user can only vote for each post one. Each vote can be a up vote or a down vote. Up votes and down votes have different vote points. +2 for an up vote and -1 for a down vote for example.\n\nWe need to cache votes_count and votes_point in post so that we can query and sort by votes_count and votes_point later.\n
  36. In SQL, we need an join table to store vote data.\n
  37. Here is the algorithm to do voting in SQL. \n\nCheck if user did not vote the post. \n\nCreate the vote.\n\nRetrieve post to get votes_point and votes_count\n\nUpdate votes_point, votes_count and save updated value to the database.\n
  38. As you see, we need fours database request to do a voting in SQL.\n
  39. \n
  40. Same for unvote\n
  41. When using Mongo, we can avoid join table by storing votes as an embedded document in post object itself.\n\nvotes.up array to store user id who give up votes\nvotes.down array to store user id who give down votes\n\nvotes.count, votes.point for querying and ordering purposes.\n
  42. Here is voting algorithm in Mongo.\n\ngive a post_id and a user_id, the query part to find the post and make sure user have not vote the post yet.\n\nThe update data part put user id to votes.up or votes.down array depend on vote value, update votes.point and votes.count.\n
  43. By using Mongo find_and_modify operator, I can query the post, do validation, update votes and return updated data in just ONE database request.\n
  44. \n
  45. Same for unvote\n
  46. I extracted the voting solution from one of your project and released it as a gem. You can install it and check source code at github. Comments and contributions are welcome.\n
  47. For summary, MongoDB is Flexible, Powerful and Fun.\n\nFlexible: come from Schema-less and document-oriented.\n\nPowerful: because Mongo is fast, scalable, and have rich queries\n\nFun: because you don&amp;#x2019;t have to think in the SQL box (tables, columns, joins ...)\n
  48. \n
  49. In case you want to know more about MongoDB, there is some selected slides in references session to know more MongoDB, Schema Design, Indexing and Query Optimization.\n