SlideShare ist ein Scribd-Unternehmen logo
1 von 27
MongoDB - case study

    Sebastian Nowak


     3 marca 2010
NoSQL

  NoSQL - po co?

      ACID nie zawsze jest potrzebny
      RDBMS nie radzą sobie z dużym wolumenem danych (TB,
      PB)
      elastyczność
NoSQL

  NoSQL - po co?

      ACID nie zawsze jest potrzebny
      RDBMS nie radzą sobie z dużym wolumenem danych (TB,
      PB)
      elastyczność


  NoSQL - wady
  Godne zaufania?
NoSQL

    CouchDB
    MongoDB
    Redis
    Neo4j
    Memcachedb
MongoDB - właściwości

      napisane w C++
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
      zaprojektowane by pracować w chmurze
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
      zaprojektowane by pracować w chmurze
      UTF-8
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
      zaprojektowane by pracować w chmurze
      UTF-8
      protokół binarny
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
      zaprojektowane by pracować w chmurze
      UTF-8
      protokół binarny
      sterowniki do wielu języków
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
      zaprojektowane by pracować w chmurze
      UTF-8
      protokół binarny
      sterowniki do wielu języków
      GridFS
MongoDB - właściwości

      napisane w C++
      dokumenty składuje jako BSON
      zaprojektowane by pracować w chmurze
      UTF-8
      protokół binarny
      sterowniki do wielu języków
      GridFS
      map-reduce, JavaScript
Capped collections

   Idealne do składowania:
       logów
       próbek pomiarów (round robin?)
    db.createCollection("books");
   db.createCollection("probes",{capped:true, size:86400});
Insert - save
    doc = { title:"Ruby wzorce projektowe", author:"Russ
   Olsen", tags:["oop","ruby"] };
   db.books.save(doc);
   db.books.save({ title:”The Ruby Way”, :author:”Obie Fernandez”,
   tags[”ruby”]});
Select - find
    db.books.findOne();
   db.books.find();
   db.books.find({title:"The Ruby Way"});
   db.books.find({tags:"ruby"});
   db.books.find({}, {title:1});
   db.books.find().skip(10).limit(10);
   db.books.find({tags:{$size: 2}});
   db.books.find({title:/Ruby/});
   db.books.find({author:{$in:["Obie Fernandez", "Russ
   Olsen", "Gabierl Garcia Marquez"]}});
   Inne modyfikatory: $ne, $in, $nin, $exist, $mod, $all, $size,
   $where
Select - group
    db.books.group({
   key:author:true,
   cond:,
   reduce: function(obj,prev) { prev.count++; },
   initial:{count:0}
   });
config/database.yml

   development:
     database: ratemymodel_development

   test:
     database: ratemymodel_test

   production:
     host:
     port: 9099
     database: ratemymodel_production
initializers/mongodb.rb

   conf = File.read("#{RAILS_ROOT}/config/database.yml")
   db_conf = YAML.load(conf)[RAILS_ENV]
   db_conf["host"] ||= "127.0.0.1"
   db_conf["port"] ||= 27017

   logger = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}_mongodb.log")

   MongoMapper.connection = Mongo::Connection.new(db_conf["host"], db_conf["port"]
     :logger => logger)
   MongoMapper.database = db_conf["database"]
test/test helper.rb

   class ActiveSupport::TestCase
     # Drop all columns after each test case.
     def teardown
       MongoMapper.database.collections.each do |coll|
         coll.remove
       end
     end

     # Make sure that each test case has a teardown
     # method to clear the db after each test.
     def inherited(base)
       base.define_method teardown do
         super
       end
     end
   end
config/environment.rb

   Rails::Initializer.run do |config|
     config.gem ’mongo_mapper’
     config.gem ’haml’
     config.gem ’will_paginate’
     config.gem ’hoptoad_notifier’
     config.gem ’carrierwave’
     config.gem ’newrelic_rpm’

     config.frameworks -= [:active_record]
     config.metals = ["GridFile"]
   end
app/models/model.rb

  # This class represents a model saved in application.
  class Model
    include MongoMapper::Document
    include MongoMapper::FindRandom

    # Fields definition
    key :name,        String,    :required => true
    key :description, String,    :required => true
    key :tags,        Array
    key :wins,        Integer,   :default => 0
    key :defeats,     Integer,   :default => 0
    key :ratio,       Float,     :default => 0
    key :user_id,     ObjectId

    # Associations
    belongs_to :user
    many :assets, :dependent => :destroy

    # Use created_at and updated_at timestamps
    timestamps!
  end
CarrierWave — konfiguracja

   # CarrierWave configuration
   CarrierWave.configure do |config|
     config.grid_fs_database = MongoMapper.database.name
     config.grid_fs_host = MongoMapper.connection.host
     config.grid_fs_access_url = "/images"
   end

   ./script/generate uploader asset
app/uploaders/asset uploader.rb

   class AssetUploader < CarrierWave::Uploader::Base
     include CarrierWave::RMagick

     storage :grid_fs

     def store_dir
       "assets/#{model.id}"
     end

     version :thumb { process :resize_to_fill => [200, 200] }

     version :comparable { process :resize_to_fill => [450,450] }

     def extension_white_list
       %w(jpg jpeg png)
     end
   end
app/models/asset.rb

   # Asset connected with model. It could be photo image etc.
   class Asset
     include MongoMapper::Document
     include MongoMapper::FindRandom

     # Uploader for image
     mount_uploader :image, AssetUploader

     # Fields definition
     key :model_id, ObjectId, :required => true

     # Callbacks
     after_destroy :remove_image_from_db

     # Associations
     belongs_to :model
   end
>>   @asset.image.url
=>   "/images/assets/4b6f009f00090d3b0c000002/10769300.jpg"
>>   @asset.image.comparable.url
=>   "/images/assets/4b6f009f00090d3b0c000002/comparable_10769300.jpg"
>>   @asset.image.thumb.url
=>   "/images/assets/4b6f009f00090d3b0c000002/thumb_10769300.jpg"
app/metals/grid file.rb

   class GridFile
     def self.call(env)
       if env["PATH_INFO"] =~ /^/images/assets/(.+)$/
         key = "assets/" + $1
         if ::GridFS::GridStore.exist?(MongoMapper.database, key)
           ::GridFS::GridStore.open(MongoMapper.database, key, ’r’) do |file|
             [200, {’Content-Type’ => file.content_type}, [file.read]]
           end
         else
           [404, {’Content-Type’ => ’text/plain’}, [’File not found.’]]
         end
       else
         [404, {’Content-Type’ => ’text/plain’}, [’File not found.’]]
       end
     end
   end
http://www.mongodb.org/display/DOCS/Home
http://mongotips.com/
http://github.com/jnunemaker/mongomapper
http://github.com/jnicklas/carrierwave
http://guides.rubyonrails.org/rails on rack.html
http://railstips.org/blog/archives/2009/12/18/why-i-think-
mongo-is-to-databases-what-rails-was-to-frameworks/
http://blog.boxedice.com/2010/02/28/notes-from-a-
production-mongodb-deployment/

Weitere ähnliche Inhalte

Was ist angesagt?

Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxDawid Rusnak
 
ansible kmonticolo bezlogo
ansible kmonticolo bezlogoansible kmonticolo bezlogo
ansible kmonticolo bezlogoKamil Monticolo
 
TorqueBox - Ruby na sterydach
TorqueBox - Ruby na sterydachTorqueBox - Ruby na sterydach
TorqueBox - Ruby na sterydachmarekgoldmann
 
Jak zostać mobile deweloperem w 1 dzień
Jak zostać mobile deweloperem w 1 dzieńJak zostać mobile deweloperem w 1 dzień
Jak zostać mobile deweloperem w 1 dzieńPaweł Kondraciuk
 
Apache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaApache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaWojciech Lichota
 
Budowa elementów GUI za pomocą biblioteki React - szybki start
Budowa elementów GUI za pomocą biblioteki React - szybki startBudowa elementów GUI za pomocą biblioteki React - szybki start
Budowa elementów GUI za pomocą biblioteki React - szybki startSages
 
Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!Wojciech Klocek
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Codesushi.co (CODESUSHI LLC)
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.jsPatryk Jar
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaMaciej Ziarko
 
TorqueBox - moc Javy, piękno Rubiego
TorqueBox - moc Javy, piękno RubiegoTorqueBox - moc Javy, piękno Rubiego
TorqueBox - moc Javy, piękno Rubiegomarekgoldmann
 
Pan Oponka - Biografia
Pan Oponka - BiografiaPan Oponka - Biografia
Pan Oponka - BiografiaFilip Tepper
 
Podstawy AngularJS
Podstawy AngularJSPodstawy AngularJS
Podstawy AngularJSSages
 
WordUp Trójmiasto - Sage 9 w praktyce
WordUp Trójmiasto - Sage 9 w praktyceWordUp Trójmiasto - Sage 9 w praktyce
WordUp Trójmiasto - Sage 9 w praktyceDawid Urbański
 

Was ist angesagt? (17)

Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/Redux
 
ansible kmonticolo bezlogo
ansible kmonticolo bezlogoansible kmonticolo bezlogo
ansible kmonticolo bezlogo
 
TorqueBox - Ruby na sterydach
TorqueBox - Ruby na sterydachTorqueBox - Ruby na sterydach
TorqueBox - Ruby na sterydach
 
Jak zostać mobile deweloperem w 1 dzień
Jak zostać mobile deweloperem w 1 dzieńJak zostać mobile deweloperem w 1 dzień
Jak zostać mobile deweloperem w 1 dzień
 
Apache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaApache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użycia
 
Budowa elementów GUI za pomocą biblioteki React - szybki start
Budowa elementów GUI za pomocą biblioteki React - szybki startBudowa elementów GUI za pomocą biblioteki React - szybki start
Budowa elementów GUI za pomocą biblioteki React - szybki start
 
GlusterFS
GlusterFSGlusterFS
GlusterFS
 
Barcamp 08/06/2010
Barcamp 08/06/2010Barcamp 08/06/2010
Barcamp 08/06/2010
 
Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.js
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
 
TorqueBox - moc Javy, piękno Rubiego
TorqueBox - moc Javy, piękno RubiegoTorqueBox - moc Javy, piękno Rubiego
TorqueBox - moc Javy, piękno Rubiego
 
Jak działa CPython
Jak działa CPythonJak działa CPython
Jak działa CPython
 
Pan Oponka - Biografia
Pan Oponka - BiografiaPan Oponka - Biografia
Pan Oponka - Biografia
 
Podstawy AngularJS
Podstawy AngularJSPodstawy AngularJS
Podstawy AngularJS
 
WordUp Trójmiasto - Sage 9 w praktyce
WordUp Trójmiasto - Sage 9 w praktyceWordUp Trójmiasto - Sage 9 w praktyce
WordUp Trójmiasto - Sage 9 w praktyce
 

Ähnlich wie Mongodb with Rails

Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Cloudskraqa
 
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...The Software House
 
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobamiElasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobamiEnterprise Search Warsaw Meetup
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychSKN Shader
 
Deployment kodu z Capistrano
Deployment kodu z CapistranoDeployment kodu z Capistrano
Deployment kodu z CapistranoMichał Szajbe
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
Testowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStackTestowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStackThe Software House
 
Przenieś się do kontenera, czyli korzyści z Docker i Docker Compose
Przenieś się do kontenera, czyli korzyści z Docker i Docker ComposePrzenieś się do kontenera, czyli korzyści z Docker i Docker Compose
Przenieś się do kontenera, czyli korzyści z Docker i Docker ComposeMariusz Bąk
 
DynamoDB – podstawy modelowania danych dla opornych
DynamoDB – podstawy modelowania danych dla opornychDynamoDB – podstawy modelowania danych dla opornych
DynamoDB – podstawy modelowania danych dla opornychThe Software House
 
Using Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentationUsing Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentationMariusz Koprowski
 
OSGi, deklaratywnie
OSGi, deklaratywnieOSGi, deklaratywnie
OSGi, deklaratywnieCode-House
 
Jak nadążyć za światem front-endu - WordPress Training Day
Jak nadążyć za światem front-endu - WordPress Training DayJak nadążyć za światem front-endu - WordPress Training Day
Jak nadążyć za światem front-endu - WordPress Training DayTomasz Dziuda
 
Paweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam HadoopPaweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam HadoopAnalyticsConf
 
Aplikacje internetowe (2010)
Aplikacje internetowe (2010)Aplikacje internetowe (2010)
Aplikacje internetowe (2010)Adrian Kalbarczyk
 
JSON, REST API
JSON, REST APIJSON, REST API
JSON, REST API3camp
 
AADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScriptAADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScriptJacek Okrojek
 

Ähnlich wie Mongodb with Rails (20)

Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
 
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
 
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobamiElasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
 
JavaScript, Moduły
JavaScript, ModułyJavaScript, Moduły
JavaScript, Moduły
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
 
Deployment kodu z Capistrano
Deployment kodu z CapistranoDeployment kodu z Capistrano
Deployment kodu z Capistrano
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
Testowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStackTestowanie rozwiązań serverless z LocalStack
Testowanie rozwiązań serverless z LocalStack
 
Przenieś się do kontenera, czyli korzyści z Docker i Docker Compose
Przenieś się do kontenera, czyli korzyści z Docker i Docker ComposePrzenieś się do kontenera, czyli korzyści z Docker i Docker Compose
Przenieś się do kontenera, czyli korzyści z Docker i Docker Compose
 
DynamoDB – podstawy modelowania danych dla opornych
DynamoDB – podstawy modelowania danych dla opornychDynamoDB – podstawy modelowania danych dla opornych
DynamoDB – podstawy modelowania danych dla opornych
 
Using Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentationUsing Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentation
 
OSGi, deklaratywnie
OSGi, deklaratywnieOSGi, deklaratywnie
OSGi, deklaratywnie
 
MongoDB 2011
MongoDB 2011MongoDB 2011
MongoDB 2011
 
Jak nadążyć za światem front-endu - WordPress Training Day
Jak nadążyć za światem front-endu - WordPress Training DayJak nadążyć za światem front-endu - WordPress Training Day
Jak nadążyć za światem front-endu - WordPress Training Day
 
Paweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam HadoopPaweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
 
Aplikacje internetowe (2010)
Aplikacje internetowe (2010)Aplikacje internetowe (2010)
Aplikacje internetowe (2010)
 
JSON, REST API
JSON, REST APIJSON, REST API
JSON, REST API
 
Platforma Kontentowa
Platforma KontentowaPlatforma Kontentowa
Platforma Kontentowa
 
Behat
BehatBehat
Behat
 
AADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScriptAADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScript
 

Mongodb with Rails

  • 1. MongoDB - case study Sebastian Nowak 3 marca 2010
  • 2. NoSQL NoSQL - po co? ACID nie zawsze jest potrzebny RDBMS nie radzą sobie z dużym wolumenem danych (TB, PB) elastyczność
  • 3. NoSQL NoSQL - po co? ACID nie zawsze jest potrzebny RDBMS nie radzą sobie z dużym wolumenem danych (TB, PB) elastyczność NoSQL - wady Godne zaufania?
  • 4. NoSQL CouchDB MongoDB Redis Neo4j Memcachedb
  • 5. MongoDB - właściwości napisane w C++
  • 6. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON
  • 7. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON zaprojektowane by pracować w chmurze
  • 8. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON zaprojektowane by pracować w chmurze UTF-8
  • 9. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON zaprojektowane by pracować w chmurze UTF-8 protokół binarny
  • 10. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON zaprojektowane by pracować w chmurze UTF-8 protokół binarny sterowniki do wielu języków
  • 11. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON zaprojektowane by pracować w chmurze UTF-8 protokół binarny sterowniki do wielu języków GridFS
  • 12. MongoDB - właściwości napisane w C++ dokumenty składuje jako BSON zaprojektowane by pracować w chmurze UTF-8 protokół binarny sterowniki do wielu języków GridFS map-reduce, JavaScript
  • 13. Capped collections Idealne do składowania: logów próbek pomiarów (round robin?) db.createCollection("books"); db.createCollection("probes",{capped:true, size:86400});
  • 14. Insert - save doc = { title:"Ruby wzorce projektowe", author:"Russ Olsen", tags:["oop","ruby"] }; db.books.save(doc); db.books.save({ title:”The Ruby Way”, :author:”Obie Fernandez”, tags[”ruby”]});
  • 15. Select - find db.books.findOne(); db.books.find(); db.books.find({title:"The Ruby Way"}); db.books.find({tags:"ruby"}); db.books.find({}, {title:1}); db.books.find().skip(10).limit(10); db.books.find({tags:{$size: 2}}); db.books.find({title:/Ruby/}); db.books.find({author:{$in:["Obie Fernandez", "Russ Olsen", "Gabierl Garcia Marquez"]}}); Inne modyfikatory: $ne, $in, $nin, $exist, $mod, $all, $size, $where
  • 16. Select - group db.books.group({ key:author:true, cond:, reduce: function(obj,prev) { prev.count++; }, initial:{count:0} });
  • 17. config/database.yml development: database: ratemymodel_development test: database: ratemymodel_test production: host: port: 9099 database: ratemymodel_production
  • 18. initializers/mongodb.rb conf = File.read("#{RAILS_ROOT}/config/database.yml") db_conf = YAML.load(conf)[RAILS_ENV] db_conf["host"] ||= "127.0.0.1" db_conf["port"] ||= 27017 logger = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}_mongodb.log") MongoMapper.connection = Mongo::Connection.new(db_conf["host"], db_conf["port"] :logger => logger) MongoMapper.database = db_conf["database"]
  • 19. test/test helper.rb class ActiveSupport::TestCase # Drop all columns after each test case. def teardown MongoMapper.database.collections.each do |coll| coll.remove end end # Make sure that each test case has a teardown # method to clear the db after each test. def inherited(base) base.define_method teardown do super end end end
  • 20. config/environment.rb Rails::Initializer.run do |config| config.gem ’mongo_mapper’ config.gem ’haml’ config.gem ’will_paginate’ config.gem ’hoptoad_notifier’ config.gem ’carrierwave’ config.gem ’newrelic_rpm’ config.frameworks -= [:active_record] config.metals = ["GridFile"] end
  • 21. app/models/model.rb # This class represents a model saved in application. class Model include MongoMapper::Document include MongoMapper::FindRandom # Fields definition key :name, String, :required => true key :description, String, :required => true key :tags, Array key :wins, Integer, :default => 0 key :defeats, Integer, :default => 0 key :ratio, Float, :default => 0 key :user_id, ObjectId # Associations belongs_to :user many :assets, :dependent => :destroy # Use created_at and updated_at timestamps timestamps! end
  • 22. CarrierWave — konfiguracja # CarrierWave configuration CarrierWave.configure do |config| config.grid_fs_database = MongoMapper.database.name config.grid_fs_host = MongoMapper.connection.host config.grid_fs_access_url = "/images" end ./script/generate uploader asset
  • 23. app/uploaders/asset uploader.rb class AssetUploader < CarrierWave::Uploader::Base include CarrierWave::RMagick storage :grid_fs def store_dir "assets/#{model.id}" end version :thumb { process :resize_to_fill => [200, 200] } version :comparable { process :resize_to_fill => [450,450] } def extension_white_list %w(jpg jpeg png) end end
  • 24. app/models/asset.rb # Asset connected with model. It could be photo image etc. class Asset include MongoMapper::Document include MongoMapper::FindRandom # Uploader for image mount_uploader :image, AssetUploader # Fields definition key :model_id, ObjectId, :required => true # Callbacks after_destroy :remove_image_from_db # Associations belongs_to :model end
  • 25. >> @asset.image.url => "/images/assets/4b6f009f00090d3b0c000002/10769300.jpg" >> @asset.image.comparable.url => "/images/assets/4b6f009f00090d3b0c000002/comparable_10769300.jpg" >> @asset.image.thumb.url => "/images/assets/4b6f009f00090d3b0c000002/thumb_10769300.jpg"
  • 26. app/metals/grid file.rb class GridFile def self.call(env) if env["PATH_INFO"] =~ /^/images/assets/(.+)$/ key = "assets/" + $1 if ::GridFS::GridStore.exist?(MongoMapper.database, key) ::GridFS::GridStore.open(MongoMapper.database, key, ’r’) do |file| [200, {’Content-Type’ => file.content_type}, [file.read]] end else [404, {’Content-Type’ => ’text/plain’}, [’File not found.’]] end else [404, {’Content-Type’ => ’text/plain’}, [’File not found.’]] end end end