MongoDb for developers. Week 1

    Good evening, habr. Last week kicked off the course «MongoDb for developers» by 10gen, which already wrote Habré . If you watched the lessons, then you can safely pass by. For the rest, welcome.

    This article will outline the main material of the first week of study. If the audience shows interest, then such posts will be published at the end of each week.

    We will briefly look at what MongoDB is, compare the difference in data structures between mongo and relational databases for a simple web application, play with the shell, and a bit of code and python.

    Why this article?I foresee a similar question. Not everyone managed to enroll in courses, not everyone has enough free time, not everyone is doing well with the perception of spoken English. Well, for googling, such material does not hurt.


    MongoDb is a non-relational database for storing JSON documents. Consider an abstract instance of the Mongo collection. We see that this document has the integer keys a and b and the fruit key which is an array. In relational databases, such behavior is impossible. It is worth noting that such a representation of the data is much closer to the code than what we deal with when working with relational databases. Collections in MongoDb are not tied to a predefined schema (schemaless). For example, the following documents may be elements of the same collection.
    {a:3
    b:7
    fruit:["apple","banana","peach"]}




    {a:1,b2}
    {a:2,b:4,c:10}

    Remember how many times you had to grind your teeth to do ALTER TABLE, adding a new field, which far not all elements will use? With MongoDb, this is a thing of the past.

    If you look at the crooked-drawn little diagram below, you can see that in the world of data storage, there are two opposite poles. Nimble, but poor in key-value storage functionality (such as memcached) and extremely functional relational databases, which, however, have problems with performance and scalability


    One of the fundamental ideas of MongoDb is to provide a wide range of features while maintaining high performance. Of course, you have to sacrifice something. For example, Mongo has no analogue to join: you cannot combine the elements of two different collections. The second important difference from relational databases is the lack of transactions. The latter sounds scary, but the fact is that in Mongo you will not need transactions, in those situations where they would be necessary when using a relational database.

    From words to deeds
    To continue, we need to install MongoDb. You are likely to find the latest version in the repository of your distribution, in the absence of such, the sources are available on the official website. There are also binaries for win and mac. It is worth noting that the 32-bit version has significant limitations on the amount of stored data, so it can only be used for development. Now for us this is not important.
    Install, run and go to the shell.

    dirtyhack@dirtyhack-ThinkPad-Edge-E125:~$ mongo
    MongoDB shell version: 2.0.4
    connecting to: test
    > 
    


    As long as we don’t have any data, mongo created for us the test base, with which we will work. Put our first element in it.

    > db.users.save({name:"Woody",age:23});
    > db.users.find().pretty()
    {
    	"_id" : ObjectId("508ea7f33cc5578ed9ecbf46"),
    	"name" : "Woody",
    	"age" : 23
    }
    > 
    

    There are many interesting things here. With the db.users.save () command, we sent a request to save the document to the users collection of the current database. This collection did not exist before; it was automatically created upon request.

    > show collections
    system.indexes
    users
    >
    

    We saved a simple json document in the users collection, with the keys name and age. The purpose of the find command is not difficult to guess - it is worth noting that in the case when we are interested in only one document, it is worth using the findOne () command. The pretty () command does not affect the logic - it simply displays the result in a readable form - without it, we would get a string, which is not convenient when working with complex objects.

    It's time to add a more complicated element to the collection, and clearly demonstrate the circuitlessness of the mongo.

    > db.users.save({name:"Bazz",age:23,place_of_birth: {country:"unknown",region:"unknown"},interests:["flying","fighting with evil"]});
    > db.users.find({name:"Bazz"}).pretty()
    {
    	"_id" : ObjectId("508eab333cc5578ed9ecbf47"),
    	"name" : "Bazz",
    	"age" : 23,
    	"place_of_birth" : {
    		"country" : "unknown",
    		"region" : "unknown"
    	},
    	"interests" : [
    		"flying",
    		"fighting with evil"
    	]
    }
    > 
    


    The second document we added is already more like real data. Note that the values ​​of the place_of_birth and interests elements are nested dictionary documents (JSONObject) and array (JSONArray), respectively. Hierarchical nesting - limited by common sense and a limit of 16 megabytes per element.

    By the way, we can use the built-in javascript interpreter
    > var j=db.users.findOne({name:"Woody"})
    > j.age=25
    25
    > db.users.save(j)
    > db.users.find({name:"Woody"}).pretty()
    {
    	"_id" : ObjectId("508ea7f33cc5578ed9ecbf46"),
    	"name" : "Woody",
    	"age" : 25
    }
    > 
    


    You've probably already noticed that each element is assigned the identifier _id. We will talk about it a little later, we only note that it is unique within the same collection.

    We use the collection in a small application at the end of the article.

    Design
    Consider what the data structure of a simple web application in Mongo and a relational database will look like.

    Imagine that we have a blog with basic functionality. Authors can publish posts by attaching tags to them, users can search by tags and leave comments on posts.

    When using a relational database, we need tables to store data about authors, posts and comments. Also, we most likely will need additional tables to store the relationships between the tables. Of course, in accordance with your realities, you can denormalize the blog base, but in its basic form, it will look something like this.


    In MongoDb, two collections will be enough for us to store similar data. I hope Mr. Erlikson's handwriting, the picture is quite legible.

    If you noticed, the author’s collection suggests using a login as a unique _id. Yes, the identifier can be set (observing the uniqueness of the course), if it is not set, the system will do it for you.
    As you can see, the data structure in mongo is noticeably simpler, and as I noted above, it is much closer to the representation of data in code.
    You are probably already tired of my outpourings, therefore, one more remark about identifiers, and let's finally.
    Setting an identifier is a high priority operation. It is set before the data is actually saved. By default, the mongo driver does not wait for a response from the database about saving data, receives an identifier and returns a response to the user. If you are not comfortable with this behavior, you can use safe mode, but be prepared for some performance loss.

    Write the code, your mother.

    In the lessons of the first week, most of the code was presented by basic classes on python and the bottle framework. In the next lessons, we will work with the course project of the blog in python and php, and for now we will create a simple application demonstrating work with MongoDb from the code.

    Due to the elementary nature of the actions, we will not create any abstractions and will do everything in the forehead (my colleagues will probably think that I got sick). I think you know how to write Tao interlaces yourself.

    We will create a simple web application that displays the names and ages of users from the users collection and allows us to add new elements to the collection.

    To run the python example, you need the pymongo driver and the bottle framework. To run the example on php, you also need a driver, you can take it from pear (do not forget to add mongo.so to the list of extensions).

    So
    Python examples
    index.py
    import bottle
    import pymongo
    import sys
    # Открываем безопасное соединение с локальной базой
    # При работе в безопасном режиме, в случае ошибки будет выброшено исключение, но их обработку мы рассмотрим позже
    # там все просто
    connection=pymongo.Connection("mongodb://localhost",safe=True)
    # будем работать с нашей тестовой базой
    db=connection.test
    @bottle.route('/')
    def home_page():
        #Получаем  все элементы коллекции
        users=db.users.find();
        return bottle.template('index',{"users":users})
    @bottle.post('/submit')
    def submit_page():
        # подготавливаем элемент из данных формы
        user={'name':bottle.request.forms.get("name"),'age':bottle.request.forms.get("age")}
        #Сохраняем
        db.users.insert(user)
        bottle.redirect('/')
    bottle.debug()
    bottle.run(host="localhost",port=8080)
    


    views / index.tpl
    Hello world

    Список пользователей

      %for user in users:
    • Имя:{{user['name']}} Возраст:{{user['age']}}
    • %end
    Добавить нового пользователя




    PHP The
    example on php differs in rare unpretentiousness

     test;     
        if ($_POST)
    	    $database -> users -> insert($_POST);
        $users = $database -> users -> find();
    ?>
    
    
    
        Hello world

    Список пользователей

    • Имя: Возраст:
    Добавить нового пользователя




    An important question to those interested in php examples. In the future, the code will be more complicated, you can use Yii or ZF, or a self-written microframework - I'm waiting for your wishes.

    That's all, I hope I tried not in vain. If the article is liked by the hawkers - next week, I will publish a report on the second week, on which CRUD operations will be considered.

    Also popular now: