Category

Category: MongoDB

Installing MongoDB in Laragon Windows

Installing MongoDB in Windows can be very confusing when you’re a beginner. Your first thought was probably to just google and find a article that will summarize it for you, well you came to the right place. Let’s dive into the installation right away

  1. Download and install the latest version of the following if you have not already:
  2. Download MongoDB PHP extension: https://pecl.php.net/package/mongodb
    • Make sure to download the correct DLL that matches your PHP version.
    • If you do not know which PHP version you’re running, right click on Laragon -> PHP > Version – you should see the version of PHP displayed here.
  3. From the start menu tray, right click on Laragon -> PHP > php.ini, then add the following code: extension=php_mongodb.dll then save the file. Then restart Laragon
  4. Test, create a PHP  file in your laragon www directory then add the following: <?php phpinfo(); then save the file. Access the file in your browser, you should see the following:

Uploading Rails App with MongoDB to Heroku

heroku

  1. Navigate to your git repository from your computer
  2. Open Gemfile then change gem ‘sqlite3’ to gem ‘pg’
  3. Run the command: “bundle install”
  4. Ensure the config/database.yml is using the postgresql adapter. by changing all “sqlite3” instance to “postgresql”
  5. At the end of Gemfile add:
    ruby “2.3.1”
    – or check version using ruby -v
  6. Login to your heroku account
    $ heroku login
  7. Create a project, CD to where your git project is located in your local computer then type in:
    $ heroku create
    – prepares Heroku to receive your source code.
  8. deploy your code by running the command:
    $ git push heroku master
  9. The application is now deployed. Ensure that at least one instance of the app is running:
    $ heroku ps:scale web=1
  10. Run the database migration:
    $ heroku run rake db:migrate
  11. Now visit the app at the URL generated by its app name. As a handy shortcut, you can open the website as follows:
    heroku open
  12. Do mongodb installation, see instructions bellow:

Installing mongodb Add-on

  1. Run the command: heroku addons:create mongolab:sandbox
  2. Run the command bellow to ensure we have MONGO_URI on our heroku config:
    $ heroku config
    It shows something like this:
    MONGODB_URI: mongodb://heroku_1c3dj371:6ncboo79ofhq5kg49ugiihe5th@ds035856.mlab.com:35856/heroku_1c3dj371
  3. Add production DB connection in your config/mongoid.yml:
    1
    2
    3
    4
    5
    6
    7
    production:
        clients:
            default:
                uri: &lt;%= ENV['MONGODB_URI'] %&gt;
            options:
                skip_version_check: true
            safe: true
  4. Commit and push your code to heroku.

To commit a code to Heroku

  • Almost every deploy to Heroku follows this same pattern. First, add the modified files to the local git repository:
    $ git add .
  • Now commit the changes to the repository:
    $ git commit -m “Demo”
  • Now deploy, just as you did previously:
    $ git push heroku master
  • Finally, check that everything is working:
    $ heroku open

Others Notes

  1. You can view information about your running app using one of the logging commands in real time using:
    $ heroku logs –tail
  2. If you changed the name of your heroku app from heroku website, you can
    perform the following command to update your local git project connection
    1. $ git remote rm heroku
    2. $ heroku git:remote -a NEW_NAME_OF_YOUR_APP

Node.js AJAX Pagination with MongoDB + Search + Sort + Filter

For this tutorial we will be using Jade Templating, you can use other templating modules but I’m afraid I wont be able to provide you further support. Jade templating is easy to learn, if you know HTML then it should only take you a few minutes to learn Jade. One rule you have to take note when using Jade is to be very careful with the spaces, this tutorial make use of tabs for indention. Another thing to note when using Jade is you can only choose one kind of indention – spaces or tabs, but you can’t use both at the same time.

This tutorial make use of Express Module so you should have that setup before getting started. I would assume that you already have basic knowledge working with MongoDB and that you already have it set up in your computer.

Required Modules

Let’s Start Coding

We first create all the fields for our search, sort and filters as well as the container that we will be using for rendering the pagination. You can save the code bellow in a file named products.jade under your views folder

extends layout

block content
    .container.products-view-all
        form.post-list
            input(type='hidden', value='')
        .clearfix
            article.navbar-form.navbar-left.p-0.m-0.ml-b
                .form-group
                    label Per Page: 
                    select.form-control.post_max.m-b
                        option(value='20') 20
                        option(value='50') 50
                        option(value='100') 100
                label Search Keyword: 
                    input.form-control.post_search_text.m-b(type='text', placeholder='Enter a keyword')
                .form-group
                    label Order By: 
                    select.form-control.post_name.m-b
                        option(value='name') Title
                        option(value='price') Price
                        option(value='quantity') Quantity
                    select.form-control.post_sort.m-b
                        option(value='ASC') ASC
                        option(value='DESC') DESC
                input.btn.btn-primary.post_search_submit.m-b(type='submit', value='Filter')
        hr
            
        .clearfix
            .pagination-container.clearfix
            .pagination-nav

Include MongoDB Connection in your app.js

/* MongoDB connection */
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest1'); // 27017 is the default port for our MongoDB instance.

To make our DB accessible to our router, add the following lines in your app.js (just above app.use(‘/’, routes);)

app.use(function(req, res, next){
    req.db = db;
    next();
});

Client Side

The script bellow is the handler of all user clicks coming from the front-end. You can save it in a file called MyPaginationClass.js under public/javascripts. Make sure to include this script file in your layout.jade 

Click here to download the FULL TUTORIAL

MongoDB Authentication Using PHP

Recently, a client of mine wanted to have an authentication system for their existing Web Application. They are currently using MongoDB as their Database and just wanted to implement a simple Login, Register and Account page for their customers.

I did not have much experience working with MongoDB before I accepted the project  so I struggled a little bit figuring out a way to make an authentication work with MongoDB, but soon after – I realized that the focus of the logic should be on PHP itself, not MongoDB. So then I started coding until I finally finished a simple session based authentication.

Instead of pasting the entire code in this page, I decided to put the project on Github.

mongodb-authentication-using-php-login-page-screenshot

Features

  • Registration page
    • Validations
    • Easy to scale fields.
    • Login and redirects on success
  • Login Page
    • Validations
    • Redirects on succes
  • Account Page
    • It simply displays the information of the user.
  • Logout

Helpers

  • is_user_logged_in();
    • Returns true if the user is logged in, otherwise it returns false.
  • current_user();
    • Returns an object containing data of the currently logged in user.

MongoDB AJAX Pagination with Search and Sort using PHP

I was recently working on a project that makes use of MongoDB as database, the client wanted to have a Paginated list of documents, Search box, Column Sorting feature and a Per Page Filter. There are over 5 million documents in their database which are basically generated tickets for their customers. Since I have an existing pagination which actually works like a charm, I thought i’d try to convert it to make use mongoDB’s query methods. I was successful in developing my client’s requests and now I just wanted to share to you guys how I did it.

The code

  1. Lets start off by making a directory in our local server, let’s call it mongodb. 
  2. I am currently using Windows as my local server and XAMPP as my web server. If you have not setup MongoDB yet and want to know how to set it up in Windows, I made a separate tutorial for that – see this link
  3. Inside our mongodb folder, create the following directories and files:
    • index.php
    • This file is basically where our pagination will be displayed.
    • Code::
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      <?php require_once('inc/config.php'); ?>
      <?php require_once('header.php'); ?>
       
      <div class="container">
          <form class = "post-list">
              <input type = "hidden" value = "" />
          </form>
         
          <article class="navbar-form navbar-left ml-b">
              <div class="form-group">
                  <label>Per Page: </label>
                  <select class="form-control post_max">
                      <option value="40">40</option>
                      <option value="80">80</option>
                      <option value="160">160</option>
                  </select>
                  <label>Search Keyword: </label>
                  <input type="text" class="form-control post_search_text" placeholder="Enter a keyword">
              </div>
              <input type = "submit" value = "Filter" class = "btn btn-primary post_search_submit" />
          </article>
         
          <br class = "clear" />
         
          <div class = "wave-box-wrapper">
              <div class = "wave-box"></div>
              <table class = "table table-striped table-post-list no-margin">
                  <thead>
                      <tr>
                          <th id = "name" class = "active"><a href = "#">Name</a></th>
                          <th id = "price"><a href = "#">Price</a></th>
                          <th id = "status"><a href = "#">Status</a></th>
                          <th id = "date"><a href = "#">Date</a></th>
                          <th id = "quantity"><a href = "#">Quantity</a></th>
                          <th>Action</th>
                      </tr>
                  </thead>
                  <tbody class = "pagination-container"></tbody>
              </table>
             
              <div class = "pagination-nav"></div>
          </div>
      </div>

      <?php require_once('footer.php'); ?>
    • header.php:
    • For this example I decided to use Bootstrap for a quick theme setup.
    • Code:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <title>MongoDB AJAX Pagination with Search and Sort | by Carlo Fontanos</title>
         
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
         
          <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
          <link rel="stylesheet" href="//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/build/css/bootstrap-datetimepicker.css">
          <link rel="stylesheet" href="css/styles.css">
      </head>
      <body class="override">
          <div class="container">
              <nav class="navbar navbar-default">
                  <div class="container-fluid">
                      <div class="navbar-header">
                          <a class="navbar-brand" href="index.php">MongoDB Example</a>
                      </div>
                  </div>
              </nav>
          </div>
    • footer.php:
    • Code:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
          <footer class="m-t">
              <div class="container">
                  <div class="panel panel-default">
                      <div class="panel-body">
                          <span class="pull-right">Copyright &copy <a href="https://carlofontanos.com" target="_blank">www.carlofontanos.com</a>; <?php echo date('Y'); ?></span>
                      </div>
                  </div>
          </footer>
         
          <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
          <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
          <script src="js/app.js"></script>
      </body>
      </html>
    • /css
      • styles.css
      • Code:
        1
        2
        3
        4
        5
        6
        7
        /* Pagination Styles */
        .pagination-nav { margin: 30px 0 20px 0; }
        .pagination-nav ul {margin: 0; padding: 0;}
        .pagination-nav ul li {display: inline-block; margin: 3px; padding: 4px 8px; background: #FFF; color: black; }
        .pagination-nav ul li.active:hover {cursor: pointer; background: #367fa9; color: white; }
        .pagination-nav ul li.inactive {background: #CACACA;}
        .pagination-nav ul li.selected {background: #367fa9; color: white;}
    • /inc
      • config.php
      • Code:
        1
        2
        $connection = new MongoClient();
        $db = $connection->selectDB('my_database_name');

        You can change the string my_database_name to anything you like.

      • view.php
      • This is where all the logic happens. If you want to integrate this with your existing app, you will have to change the document field names to match your requirements. For this example I would assume you have a database with the following document fields:

        • name (string)
        • price (string)
        • status (string)
        • date (string)
        • quantity (string)
      • Code:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        95
        96
        97
        98
        99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
        120
        121
        122
        123
        124
        125
        126
        127
        128
        129
        130
        131
        132
        133
        134
        135
        136
        137
        138
        139
        140
        141
        142
        143
        144
        145
        146
        require_once('config.php');

        $collection = $db->products;
        $pag_content = '';
        $pag_navigation = '';

        if( isset( $_POST['data']['page'] ) ){
           
            $page = $_POST['data']['page']; /* The page we are currently at */
            $name = $_POST['data']['th_name']; /* The name of the column name we want to sort */
            $sort = $_POST['data']['th_sort']; /* The order of our sort (DESC or ASC) */
            $max  = $_POST['data']['max']; /* Number of items to display per page */
            $cur_page = $page;
            $page -= 1;
            $per_page = $max ? $max : 40;
            $previous_btn = true;
            $next_btn = true;
            $first_btn = true;
            $last_btn = true;
            $start = $page * $per_page;
           
            $where_search = array();
           
            /* Check if there is a string inputted on the search box */
            if( ! empty( $_POST['data']['search']) ){
                /* If a string is inputted, include an additional query logic to our main query to filter the results */
                $filter = new MongoRegex('/' . $_POST['data']['search'] . '/i');
                $where_search = array(
                    '$or' => array(
                        array('name' => $filter),
                        array('price' => $filter)
                    )
                );
            }
           
            /* Retrieve all the posts */
            $all_items = $collection
                ->find( $where_search, array('_id', 'name', 'price', 'status', 'date', 'quantity') )
                ->limit( $per_page )
                ->skip( $start )
                ->sort( array(
                    $name => $sort == 'ASC' ? 1 : -1
                ));
           
            $count = $collection
                ->find($where_search)
                ->count();
               
            /* Check if our query returns anything. */
            if( $count ){
               
                /* Iterate thru each item */
                foreach( $all_items as $key => $item ){
                   
                    $item = (object) $item;
                    $status = $item->status == 1 ? 'Active' : 'Inactive';
                   
                    $pag_content .= '
                    <tr>
                        <td>'
        . $item->name . '</td>
                        <td>$'
        . $item->price . '</td>
                        <td>'
        . $status . '</td>
                        <td>'
        . date("F j, Y, g:i a", strtotime( $item->date ) ) . '</td>
                        <td>'
        . $item->quantity . '</td>
                        <td>
                            <a href="#_" class="text-success"><span class="glyphicon glyphicon-pencil" title="Edit"></span></a> &nbsp; &nbsp;
                            <a href="#_" class="text-danger delete-product" item_id="'
        . $item->_id . '"><span class="glyphicon glyphicon-remove" title="Delete"></span></a>
                        </td>
                    </tr>'
        ;        
                }
               
            /* If the query returns nothing, we throw an error message */
            } else {
                $pag_content .= '<td colspan = "7" class = "bg-danger p-d">No results found.</td>';
               
            }

            $pag_content = $pag_content . "<br class = 'clear' />";
           
            $no_of_paginations = ceil($count / $per_page);

            if ($cur_page >= 7) {
                $start_loop = $cur_page - 3;
                if ($no_of_paginations > $cur_page + 3)
                    $end_loop = $cur_page + 3;
                else if ($cur_page <= $no_of_paginations && $cur_page > $no_of_paginations - 6) {
                    $start_loop = $no_of_paginations - 6;
                    $end_loop = $no_of_paginations;
                } else {
                    $end_loop = $no_of_paginations;
                }
            } else {
                $start_loop = 1;
                if ($no_of_paginations > 7)
                    $end_loop = 7;
                else
                    $end_loop = $no_of_paginations;
            }
             
            $pag_navigation .= "<ul>";

            if ($first_btn && $cur_page > 1) {
                $pag_navigation .= "<li p='1' class='active'>First</li>";
            } else if ($first_btn) {
                $pag_navigation .= "<li p='1' class='inactive'>First</li>";
            }

            if ($previous_btn && $cur_page > 1) {
                $pre = $cur_page - 1;
                $pag_navigation .= "<li p='$pre' class='active'>Previous</li>";
            } else if ($previous_btn) {
                $pag_navigation .= "<li class='inactive'>Previous</li>";
            }
            for ($i = $start_loop; $i <= $end_loop; $i++) {

                if ($cur_page == $i)
                    $pag_navigation .= "<li p='$i' class = 'selected' >{$i}</li>";
                else
                    $pag_navigation .= "<li p='$i' class='active'>{$i}</li>";
            }
           
            if ($next_btn && $cur_page < $no_of_paginations) {
                $nex = $cur_page + 1;
                $pag_navigation .= "<li p='$nex' class='active'>Next</li>";
            } else if ($next_btn) {
                $pag_navigation .= "<li class='inactive'>Next</li>";
            }

            if ($last_btn && $cur_page < $no_of_paginations) {
                $pag_navigation .= "<li p='$no_of_paginations' class='active'>Last</li>";
            } else if ($last_btn) {
                $pag_navigation .= "<li p='$no_of_paginations' class='inactive'>Last</li>";
            }

            $pag_navigation = $pag_navigation . "</ul>";   
        }


        $response = array(
            'content'       =>  $pag_content,
            'navigation'    =>  $pag_navigation,
        );

        echo json_encode( $response );

        exit();
    • /js
      • app.js
      • This app js class handles column sorting, searching, pagination clicks, and filter.
      • Code:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        95
        96
        97
        98
        99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
        120
        121
        122
        123
        124
        125
        126
        127
        128
        129
        130
        131
        132
        133
        134
        135
        136
        137
        138
        139
        140
        141
        142
        143
        144
        145
        146
        147
        148
        /**
         * App Class
         *
         * @author      Carl Victor Fontanos
         * @author_url  www.carlofontanos.com
         *
         */


        /**
         * Setup a App namespace to prevent JS conflicts.
         */

        var app = {
               

            Posts: function() {
               
                /**
                 * This method contains the list of functions that needs to be loaded
                 * when the "Posts" object is instantiated.
                 *
                 */

                this.init = function() {
                    // this.loaded_posts_pagination();
                    this.get_items_pagination();
                }
               
                /**
                 * Load items pagination.
                 */

                this.get_items_pagination = function() {
                   
                    _this = this;
                   
                    /* Check if our hidden form input is not empty, meaning it's not the first time viewing the page. */
                    if($('form.post-list input').val()){
                        /* Submit hidden form input value to load previous page number */
                        data = JSON.parse($('form.post-list input').val());
                        _this.ajax_get_items_pagination(data.page, data.th_name, data.th_sort);
                    } else {
                        /* Load first page */
                        _this.ajax_get_items_pagination(1, 'name', 'ASC');
                    }
                   
                    var th_active = $('.table-post-list th.active');
                    var th_name = $(th_active).attr('id');
                    var th_sort = $(th_active).hasClass('DESC') ? 'DESC': 'ASC';
                               
                    /* Search */
                    $('body').on('click', '.post_search_submit', function(){
                        _this.ajax_get_items_pagination(1, th_name, th_sort);
                    });
                    /* Search when Enter Key is triggered */
                    $(".post_search_text").keyup(function (e) {
                        if (e.keyCode == 13) {
                            _this.ajax_get_items_pagination(1, th_name, th_sort);
                        }
                    });
                   
                    /* Pagination Clicks   */                  
                    $('body').on('click', '.pagination-nav li.active', function(){
                        var page = $(this).attr('p');
                        var current_sort = $(th_active).hasClass('DESC') ? 'DESC': 'ASC';
                        _this.ajax_get_items_pagination(page, th_name, current_sort);                
                    });

                    /* Sorting Clicks */
                    $('body').on('click', '.table-post-list th', function(e) {
                        e.preventDefault();                            
                        var th_name = $(this).attr('id');
                                                           
                        if(th_name){
                            /* Remove all TH tags with an "active" class */
                            if($('.table-post-list th').removeClass('active')) {
                                /* Set "active" class to the clicked TH tag */
                                $(this).addClass('active');
                            }
                            if(!$(this).hasClass('DESC')){
                                _this.ajax_get_items_pagination(1, th_name, 'DESC');
                                $(this).addClass('DESC');
                            } else {
                                _this.ajax_get_items_pagination(1, th_name, 'ASC');
                                $(this).removeClass('DESC');
                            }
                        }
                    });
                }
               
                /**
                 * AJAX items pagination.
                 */

                this.ajax_get_items_pagination = function(page, th_name, th_sort){
                   
                    if($(".pagination-container").length){
                        $(".pagination-container").html('<img src="img/loading.gif" class="ml-tb" />');
                       
                        var post_data = {
                            page: page,
                            search: $('.post_search_text').val(),
                            th_name: th_name,
                            th_sort: th_sort,
                            max: $('.post_max').val(),
                        };
                       
                        $('form.post-list input').val(JSON.stringify(post_data));
                       
                        var data = {
                            action: "demo_load_my_posts",
                            data: JSON.parse($('form.post-list input').val())
                        };
                       
                        $.ajax({
                            url: 'inc/view.php',
                            type: 'POST',
                            data: data,
                            success: function (response) {
                                response = JSON.parse(response);
                               
                                if($(".pagination-container").html(response.content)){
                                    $('.pagination-nav').html(response.navigation);
                                    $('.table-post-list th').each(function() {
                                        /* Append the button indicator */
                                        $(this).find('span.glyphicon').remove();    
                                        if($(this).hasClass('active')){
                                            if(JSON.parse($('form.post-list input').val()).th_sort == 'DESC'){
                                                $(this).append(' <span class="glyphicon glyphicon-chevron-down pull-right"></span>');
                                            } else {
                                                $(this).append(' <span class="glyphicon glyphicon-chevron-up pull-right"></span>');
                                            }
                                        }
                                    });
                                }
                            }
                        });
                    }
                }
            }
        }

        /**
         * When the document has been loaded...
         *
         */

        jQuery(document).ready( function () {
           
            posts = new app.Posts(); /* Instantiate the Posts Class */
            posts.init(); /* Load Posts class methods */
           
        });
  4. I can’t provide a demo link at the moment as I am only running my site in a shared hosting, but I do hope that you find this tutorial useful.

Challenge

Continue working on the Edit and Delete buttons.

Installing MongoDB in XAMPP Windows

  • Go to your c:/ drive and create a folder “mongodb
  • Download mongoDB from this link: http://www.mongodb.org/downloads (the download button is located under “Community Server” tab)
  • Select “Custom” when installing the software

mong-db-custom-installation

  • Install mongoDB in the following path: c:/mongodb
  • Go to your c:/ drive then create a new folder “data“, inside it create another folder “db
  • Start MongoDB in your command prompt by executing the following command: C:\mongodb\bin\mongod.exe

mongo-db-successfully-running

Congratulations, you have successfully installed MongoDB  in Windows.

Moving on, let us now configure XAMPP

To verify that you have successfully configured mongoDB in XAMPP, create a file in your xampp/htdocs folder, in it put the following code:

1
<!--?php &lt;br ?--> phpinfo();

Now access this file in your browser. Ex. “localhost/testfile.php”

You should see that MongoDB is already installed:

mongodb-successful-installation