Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Getting started with Ruby and MongoDB using Software Collections

March 25, 2014
Josef Stříbný
Related topics:
Linux
Related products:
Red Hat Enterprise Linux

Share:

    MongoDB became recently a very popular document database and RHSCL 1.1 includes both mongodb24 and ror40 Software Collections including the supported Ruby drivers for MongoDB.  So let's have a short look on what MongoDB actually is and how to get started using MongoDB from Ruby using Software Collections. Note that we will use ruby200, ror40, mongodb24 and v8 collections together on RHEL 7 Beta, although you can follow this article with RHEL 6 as well. If you need to use Ruby 1.9.3, you can use ruby193 Software Collection that contains the MongoDB adapters as well (in RHSCL 1.1) and the only apparent difference is that ruby193 is not split into Ruby and Ruby on Rails collections so all the gems are available in ruby193.

    What is MongoDB

    MongoDB is an open-source document database getting a lot of traction and used by some big enterprises like Craigslist and SourceForge. If you still haven't heard of it, you should know that the main difference from traditional relational database management systems (RDBMS) is that it provides a dynamic table-less schema. Data are saved like documents that can contain other documents (you can think of the document as an object in Ruby). Documents then contain elements which are basically JSON-like fields and value pairs. Since you don't need a fixed database schema for your attributes, no migrations are necessary. Moreover MongoDB is built for speed and performance in a distributed environment offering features like sharding (which is a process how to save data on more physical devices) and map-reduce (a paradigm for efficient mapping and reducing a data selection into aggregated results).

    BSON

    BSON is the actual JSON-like format used internally by MongoDB to store data. It's a binary format in which zero or more fields and value pairs are stored like one entity which is called a document. If you look on the following hash {"hello": "world"} then

    "x16x00x00x00x02hellox00
     x06x00x00x00worldx00x00"

    is its representation in BSON. The basic types are as follows: byte (1 byte as 8 bits), int32 (4 bytes as 32-bit signed integer), int64 (8 bytes as 64-bit signed integer) and double (8 bytes as 64-bit IEEE 754 floating point) and represent the terminals of the BSON grammar. In the above example "hello" is represented as hellox00. So x00 and others are the terminals. Elements (key-value pairs), sequence of elements and document itself are then non-terminals of the grammar. You can go and read the full spec at www.bsonspec.org, but simply said MongoDB implements this binary BSON format for storing the data and it's just sort of a nested hash which is very alike to the one in Ruby itself.

    Installation of MongoDB

    Installation of MongoDB client and server using Software Collections is fairly easy:

    $ su -c "yum install -y mongodb24 mongodb24-mongodb"

    mongodb24 is the meta package for the collection that will pull in the mongodb24-mongodb-server package that we need for running MongoDB as a server. mongodb24-mongodb is a client (shell) that is not automatically installed so we need to list it explicitly (mongodb24 Software Collection contains more clients and therefore it installs only the server part of MongoDB alongside the meta package). But most important is mongodb24-mongodb-server that contains the server part of MongoDB including the config and init files. Notice that v8314-v8 is also automatically installed with MongoDB as its dependency. v8314 is a Software Collection of v8, the famous JavaScript engine from Google Chrome.

    After the installation is done, let's see if the mongodb24 is available and enable it:

    $ scl -l
    mongodb24
    v8314
    $ scl enable mongodb24 bash

    That should enable both mongodb24 and v8314 since mongodb24 needs v8314 to run.
    Then we can start the MongoDB server from the collection and check whether it runs:

    $ su -c "systemctl start mongodb24-mongod.service"
    $ su -c "systemctl status mongodb24-mongod.service"
    mongodb24-mongod.service - High-performance, schema-free document-oriented database
       Loaded: loaded (/usr/lib/systemd/system/mongodb24-mongod.service; disabled)
       Active: active (running) since Thu 2014-02-27 17:24:33 CET; 6s ago
      Process: 3233 ExecStart=/usr/bin/scl enable $MONGODB24_SCLS_ENABLED -- /opt/rh/mongodb24/root/usr/bin/mongod $OPTIONS run (code=exited, status=0/SUCCESS)
     Main PID: 3243 (mongod)
       CGroup: /system.slice/mongodb24-mongod.service
               └─3243 /opt/rh/mongodb24/root/usr/bin/mongod --quiet -f /opt/rh/mo...
    
    Feb 27 17:24:24 localhost.localdomain systemd[1]: Starting High-performance, ...
    Feb 27 17:24:24 localhost.localdomain scl[3233]: about to fork child process....
    Feb 27 17:24:24 localhost.localdomain scl[3233]: forked process: 3243
    Feb 27 17:24:24 localhost.localdomain scl[3233]: all output going to: /var/l...g
    Feb 27 17:24:33 localhost.localdomain scl[3233]: child process started succe...g
    Feb 27 17:24:33 localhost.localdomain systemd[1]: Started High-performance, s...
    Hint: Some lines were ellipsized, use -l to show in full.

    If you are not yet running RHEL 7 beta, you will need to change those commands to su -c "service mongodb24-mongod {start,status}" for RHEL 6.

    Then let's try out the MongoDB client known as mongo shell:

    $ mongo
    MongoDB shell version: 2.4.9
    connecting to: test
    Welcome to the MongoDB shell.
    For interactive help, type "help".
    For more comprehensive documentation, see
    	http://docs.mongodb.org/show databases
    Questions? Try the support group
    	http://groups.google.com/group/mongodb-user
    >

    And let's save some data to a new database:

    > show dbs
    local	0.078125GB
    > use my_db
    switched to db my_db
    > db.products.insert( { item: "First item" } )
    > db.products.find()
    { "_id" : ObjectId("530f6896b3ae9716674004e9"), "item" : "First item" }
    > show databases
    local	0.078125GB
    my_db	0.203125GB

    As you can see we can list databases with show dbs or show databases, we switch databases with use [database_name] and access currently selected database and its collections with db. MongoDB has collections and objects instead of tables and rows so we can immediately start inserting objects as hashes. Notice that our my_db was also created automatically.

    The most interesting thing to explain here is the _id attribute with the ObjectId("530f6896b3ae9716674004e9") value. You can think of it as a primary key from relational databases. It's most likely unique and created automatically by MongoDB. Internally it is a BSON type represented by a 4-byte value representing the seconds since the Unix epoch, a 3-byte machine identifier, a 2-byte process id, and a 3-byte counter, starting with a random value. Therefore we can actually get the time and date of creation of the object from this ObjectID:

    > ObjectId("530f6896b3ae9716674004e9").getTimestamp()

    For more information about mongo shell check the reference manual. When you are done playing in the mongo shell, type exit to exit.

    Official Ruby client

    In RHSCL 1.1 beta we now ship rubygem-mongo, the official Ruby adapter for MongoDB. Let's try to install it and connect to our existing database from Ruby.

    You can install it by running:

    su -c "yum install ror40-rubygem-mongo ror40-rubygem-bson_ext"

    Installing MongoDB Ruby client should pull in the ror40-rubygem-bson, but you can also install ror40-rubygem-bson_ext for the bson gem to use the faster C extension.

    $ scl enable ror40 bash

    This will enable also ruby200 Software Collection as a dependency. Before we take a look on the mongo gem, let's see how you can work with BSON format itself:

    irb(main):004:0> require 'bson'
    irb(main):005:0> hash = { "attribute" => "value", :'2' => 3 }
    => {"attribute"=>"value", :"2"=>3}
    irb(main):006:0> bson = BSON.serialize(hash)
    => #<BSON::ByteBuffer:0x00000001d188b8 @str="!x00x00x00x02attributex00x06x00x00x00valuex00x102x00x03x00x00x00x00", @cursor=33, @max_size=4194304>
    irb(main):007:0> BSON.deserialize(bson)
    => {"attribute"=>"value", "2"=>3}

    We can easily create BSON from any Ruby hash with BSON.serialize(hash) or convert it back using BSON.deserialize(bson). This is what mongo will internally use.

    Now we can move on to use mongo driver. If we want to create a connection to MongoDB we need to know the host and port. The default port for MongoDB is 27017 and we are connecting to localhost:

    irb(main):010:0> require 'mongo'
    => true
    irb(main):011:0> mongo_client = Mongo::MongoClient.new('localhost', 27017)
    => #<Mongo::MongoClient:0x00000000d44d88 @host="localhost", @port=27017, @id_lock=#, @primary=["localhost", 27017], @primary_pool=#, @mongos=false, @tag_sets=[], @acceptable_latency=15, @max_message_size=48000000, @max_bson_size=16777216, @slave_ok=nil, @ssl=nil, @unix=false, @socket_opts={}, @socket_class=Mongo::TCPSocket, @auths=[], @pool_size=1, @pool_timeout=5.0, @op_timeout=nil, @connect_timeout=30, @logger=nil, @read=:primary, @default_db="test", @write_concern={:w=>1, :j=>false, :fsync=>false, :wtimeout=>nil}, @read_primary=true>

    If that worked we can go on and access our previously created database:

    irb(main):012:0> mongo_client.database_names
    => ["local", "my_db"]
    irb(main):013:0> mongo_client.database_info.each { |info| puts info.inspect }
    ["local", 83886080]
    ["my_db", 218103808]
    => {"local"=>83886080, "my_db"=>218103808}
    irb(main):014:0> db = mongo_client.db('my_db')
    => #<Mongo::DB:0x00000000d665c8 @name="my_db", @connection=#<Mongo::MongoClient:0x00000000d44d88 @host="localhost", @port=27017, @id_lock=#, @primary=["localhost", 27017], @primary_pool=#, @mongos=false, @tag_sets=[], @acceptable_latency=15, @max_message_size=48000000, @max_bson_size=16777216, @slave_ok=nil, @ssl=nil, @unix=false, @socket_opts={}, @socket_class=Mongo::TCPSocket, @auths=[], @pool_size=1, @pool_timeout=5.0, @op_timeout=nil, @connect_timeout=30, @logger=nil, @read=:primary, @default_db="test", @write_concern={:w=>1, :j=>false, :fsync=>false, :wtimeout=>nil}, @read_primary=true>, @strict=nil, @pk_factory=nil, @write_concern={:w=>1, :j=>false, :fsync=>false, :wtimeout=>nil}, @read=:primary, @tag_sets=[], @acceptable_latency=15, @cache_time=300>

    We can see that our my_db database is there. So we select it using Mongo::Connection#db method. It could be wise to check also our collections:

    irb(main):015:0> Mongo::DB.instance_methods
    => [:strict=, :strict?, :name, :write_concern, :connection, :cache_time, :cache_time=, :read, :read=, :tag_sets, :tag_sets=, :acceptable_latency, :acceptable_latency=, :authenticate, :issue_authentication, :add_stored_function, :remove_stored_function, :add_user, :remove_user, :logout, :issue_logout, :collection_names, :collections, :collections_info, :create_collection, :collection, :[], :drop_collection, :get_last_error, :error?, :previous_error, :reset_error_history, :dereference, :eval, :rename_collection, :drop_index, :index_information, :stats, :ok?, :command, :full_collection_name, :pk_factory, :pk_factory=, :profiling_level, :profiling_level=, :profiling_info, :validate_collection, :legacy_write_concern, :write_concern_from_legacy, :get_write_concern, :nil?, :===, :=~, :!~, :eql?, :hash, :, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
    irb(main):016:0> db.collection_names
    => ["system.indexes", "products"]

    I listed the instance methods for Mongo::DB and found out that I can use #collection_names method to list my collections. The "products" collection is really there, but it's not the only collection in the database. So what about this "system.indexes"? As the name suggests it's a collection for this database indexes. It's a system collection that MongoDB creates automatically. There are also other system collections that MongoDB can create so it's better to avoid naming your collections "system.*" altogether.

    And that's it for today. For the next steps check the mongo gem manual.

    Don't forget you need to always enable both ror40 and mongodb24 collections. You can do so with:

    $ scl enable ror40 mongodb24 bash

    And check that all four collections are enabled by running:

    $ env | grep X_SCLS
    X_SCLS=ruby200 v8314 mongodb24 ror40

    Sources:

    • http://www.bsonspec.org/
    • http://docs.mongodb.org/manual/reference/mongo-shell/
    • https://www.mongodb.com/docs/manual/reference/system-collections/
    • http://api.mongodb.org/ruby/1.9.2/
    Last updated: October 8, 2024

    Recent Posts

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    • How to integrate vLLM inference into your macOS and iOS apps

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue