{"id":34,"date":"2011-02-28T12:44:00","date_gmt":"2011-02-28T12:44:00","guid":{"rendered":"http:\/\/localhost:10265\/?p=33"},"modified":"2011-08-16T00:10:52","modified_gmt":"2011-08-16T00:10:52","slug":"an-introduction-to-mongodb","status":"publish","type":"post","link":"https:\/\/mehdi.biz\/blog\/2011\/02\/28\/an-introduction-to-mongodb\/","title":{"rendered":"An introduction to MongoDB"},"content":{"rendered":"<!-- google_ad_section_start --><p><img loading=\"lazy\" decoding=\"async\" alt=\"MongoDB logo\" width=\"200\" height=\"67\" src=\"\/blog\/wp-content\/uploads\/2011\/08\/mongodb-logo.png\" style=\"border: none; padding: 5px;\" \/>10 years ago we have had no social network service in such a scale we used to see these days. <a href=\"http:\/\/www.facebook.com\/\">Facebook<\/a>, for instance, has got more than 600 million active users who modify their personal profiles, exchange messages, play games and the like every single day. Consider the total committed transactions per second caused by these interactions. Clearly, things have changed and, hence, we need to deal with those changes as well. We actually need something that accommodates itself to such huge volume of data requirements.<\/p>\n<h4>Do relational databases handle such use cases in a graceful manner?<\/h4>\n<p>The answer is yes, they do. However, the problem is actually scaling!<\/p>\n<p>When a web application becomes popular and the usage goes up, the requests start queuing up, because of those locks that have been placed on different portions of the database. This means that user B has to wait for user\u2019s A request to be processed. Under very heavy load, this becomes a bottleneck.<\/p>\n<p>Such problems are usually addressed by &#8220;vertical scaling&#8221;, say, adding more memory to the hardware, replacing the current CPU with a faster one and so force. This might accommodate the current growth for a while but you\u2019ll be faced with those conditions all over again.<\/p>\n<p>Soon enough, you\u2019ll notice that your hardware doesn\u2019t support more than a given total amount of CPUs\/RAMs whilst you have incorporated the best hard disc options available out there. So, naturally, you\u2019ll set up the next server in a database cluster. This, however, introduces a new problem: dealing with data replication and consistency.<\/p>\n<p>Now you need to make sure that data is consistent during the application operations, both under normal and failover conditions.<\/p>\n<p>At the same time, you probably modify the database design and de-normalize some tables, tune some indexes and etc. This, however, could introduce new problems and new unwanted changes in the application layer.<\/p>\n<h4>Don\u2019t get me wrong!<\/h4>\n<p>I do not say that such huge-scaled web scenarios cannot be handled by traditional database models (and in particular, the relational model) that have been around for decades.<\/p>\n<p>However, the point is to understand that the relational model is simply a model. That is, it\u2019s useful to handle certain problem domains. This certainly doesn\u2019t close the case on other ways of representing data.<\/p>\n<p>I\u2019ve seen a couple of articles\/<a href=\"http:\/\/highscalability.com\/blog\/2010\/9\/5\/hilarious-video-relational-database-vs-nosql-fanbois.html\">video<\/a>s lately about &#8220;NoSQL vs. SQL&#8221; that seemed to have caught a lot of attention. Some people tend to say <a href=\"http:\/\/buytaert.net\/nosql-and-sql\">schema-free dbs are a mess<\/a> or <a href=\"http:\/\/blog.flaper87.org\/2010\/05\/9\/whats-so-good-about-nosql-part-1\/\">why NoSQL dbs are so great over relational ones<\/a>! This, however, doesn\u2019t actually stand true. &#8220;SQL and NoSQL&#8221; dbs are not against each other.<\/p>\n<h4>What is MongoDB?<\/h4>\n<p>MongoDB (from &#8220;hu<b>mongo<\/b>us&#8221;) is a scalable, high-performance, open source, document-oriented, schema-free database storage engine written in C++.<\/p>\n<p>It uses a lightweight binary format, called BSON (Binary JSON) to read\/write documents (an ordered set of keys with associative values) that is roughly equivalent to a row in an RDBMS. These documents can be grouped into a schema-free set called a collection. Theses collection can be further divided conventionally into namespaces that is nothing more than different collections separated by a period.<\/p>\n<p>MongoDB uses <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms810613.aspx\">memory-mapped files<\/a> to store\/retrieve data. Once a file has been memory-mapped, the content could be accessed by dereferencing a pointer. This way, it pushes most of its memory management job to the OS which results in a much cleaner (and safer) code in MongoDB (it has several benefits; however, it\u2019s out of the scope of this article). <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Philosophy\">The philosophy<\/a> behind it states that whenever possible, the engine has to offload processing and logic to the client side.<\/p>\n<p>Each database consists of different files named <dbname>.0, <dbname>.1, and so forth. The first one is pre-allocated into 64MB (prefilled with zero bytes); the second one doubles this size, say, 128MB and etc up to the maximum file size of 2GB. Once this happens, each successive file will be also 2GB. This prevents file system fragmentation and provides a non-blocking mechanism to handle requests when the need for extract space arises.<\/p>\n<p>MongoDB uses a lightweight TCP\/IP wire protocol to expose it\u2019s functionality to client-side programs (including <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Drivers\">drivers<\/a>). It uses TCP port 27017 (by default) to listen to the connections and exposes some of its administrative features on port 28017.<\/p>\n<h4>Getting Started<\/h4>\n<p>MongoDB can be installed on Solaris, <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Quickstart+OS+X\">OS X<\/a>, <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Quickstart+Unix\">Linux<\/a> and Windows (32bit\/64bit). This paper, however, will focus on installing MongoDB on Microsoft Windows. You can consult <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Quickstart\">this page<\/a> for additional information on how to get MongoDB up and running on other operating systems.<\/p>\n<h4>Installing MongoDB on Microsoft Windows<\/h4>\n<p>Follow <a href=\"http:\/\/www.mongodb.org\/downloads\">this URL<\/a> and download the latest &#8220;Production Release&#8221; that\u2019s suitable for your version of Windows (32bit\/64bit). At the time of this writing, the latest production release of MongoDB is 1.6.5 which can be downloaded using one the following links:<\/p>\n<ul>\n<li><a href=\"http:\/\/downloads.mongodb.org\/win32\/mongodb-win32-i386-1.6.5.zip\">32-bit Windows<\/a> (11.6MB)<\/li>\n<li><a href=\"http:\/\/downloads.mongodb.org\/win32\/mongodb-win32-x86_64-1.6.5.zip\">64-bit Windows<\/a> (14.6MB)<\/li>\n<\/ul>\n<p>Once the file is downloaded, unzip it to a folder of your choice. It contains a bin directory which contains several executables. MongoDB uses the directory &#8220;c:datadb&#8221; to store data files by default; however, you can modify it if you want. However, please note that this directory is not created by default, so launching MongoDB engine will throw an exception of &#8220;dbpath (\/data\/db) does not exist&#8221; and terminates the process.<\/p>\n<p>Therefore, make sure that you create the folder before going on. Assuming you\u2019ve created the &#8220;d:mongodbdb&#8221; directory, the next step is to launch the MongoDB engine using the following command-line:<\/p>\n<p><code>mongod --dbpath \"d:mongodbdb\"<\/code><\/p>\n<p>This starts the MongoDB engine and prints the process id, db path, port number and some other information on the console window. You can stop the currently running engine by pressing the CTRL-C on your keyboard.<\/p>\n<p>MongoDB can also be installed as an NT-Service. To do so, you can enter the following command line:<\/p>\n<p><code>mongod --dbpath \"d:mongodbdb\" --logpath \"d:mongodbdbdblog.log\" --install<\/code><\/p>\n<p>Now, open up the services panel (from the Windows Control Panel), find the MongoDB service, right-click on it, and press start. If the service is started successfully, it\u2019s logged in the dblog.log text file. (This might fail for a couple of reasons one of which is that the port# 27017\/28017 is used by some other application on your system or it\u2019s blocked by your firewall application).<\/p>\n<p>However, the default port could be easily modified using the &#8211;port switch. (You can get an extensive help to mongod.exe by launching it using <b>mongodb\/?<\/b> from the command line).<\/p>\n<h4>MongoDB Shell<\/h4>\n<p>The standard MongoDB distribution comes with a JavaScript interpreter (obviously, called MongoDB Shell) that is used for development\/prototyping, administrative operations, lightweight scripting and testing purposes. It\u2019s a standalone MongoDB client with built-in support for MongoDB connectivity.<\/p>\n<p>Open up the console window and change the directory to the bin directory where you unzipped the MongoDB distribution. Among the executables there, it\u2019s a program named mongo.exe. To start the shell, run the mongo.exe:<\/p>\n<p><code><br \/>\nD:mongodb-win32-i386-1.6.5bin>mongo.exe<br \/>\nMongoDB shell version: 1.6.5<br \/>\nconnecting to: test<br \/>\n><br \/>\n<\/code><\/p>\n<p>The shell automatically connects to the MongoDB instance on default ports (Make sure that your firewall software doesn\u2019t prevent that). If you\u2019ve installed it on a different port, you need to launch mongo.exe using the following command line syntax:<\/p>\n<p><code>mongo 192.168.1.100:1234\/test<\/code><\/p>\n<p>This connects to the test database on <b>192.168.1.100<\/b> on <b>1234<\/b> port.<\/p>\n<h4>Understanding the basics<\/h4>\n<p>When the MongoDB shell starts, it automatically connects to the &#8220;test&#8221; database and the connection is then assigned to a JavaScript variable named <b>db<\/b>. This global variable is used throughout the shell, providing us with the ability to perform CRUD operations (we will examine this soon).<\/p>\n<p>When you type a JavaScript variable at the MongoDB shell, it is converted to its string representation. For example, type <b>db<\/b> at the shell prompt and press the Enter key to get the default database name (in this case, &#8220;test&#8221;). You can also write your own JavaScript code. For example, enter the following code block in the MongoDB shell:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar sum = 0;\r\nfor (var i = 1; i &lt;= 100; i++) {\r\n    sum += i;\r\n}\r\n<\/pre>\n<p>Please note that the shell is enough smart to detect whether the JavaScript statement is complete. If the statement is not completed yet (and you press the Enter key), you\u2019ll get a \u2026 prompt. The above code simply calculates the sum of the series 1-100 that is equal to 5050. Amazingly, you\u2019ll get 5050 at prompt when you\u2019re done with the code.<\/p>\n<p>You can also load a given JavaScript file using the load command. To examine this, create a text file named &#8220;my_script.js&#8221; in the bin directory containing the following lines:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction getSum(upperBound) {\r\n    var sum = 0;\r\n    for (var i = 1; i &lt;= upperBound; i++) {\r\n        sum += i;\r\n    }\r\n    return sum;\r\n}\r\n<\/pre>\n<p>Now, from the MongoDB shell, enter the following commands to load the JavaScript file and run the getSum function respectively:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nload(&quot;my_script.js&quot;);\r\ngetSum(100);\r\n<\/pre>\n<p>(Please note that there are other means of loading JavaScript files too, but let\u2019s don\u2019t get into details the purpose of this article. You can always get a built-in help by entering help in the shell prompt.)<\/p>\n<p>Well, the above code produces the output 5050 as expected. Now, enter the getSum (without parenthesis) at the MongoDB prompt and hit the Enter. Amazingly, you will see the source code of the function.<\/p>\n<p>With this information in hand, let\u2019s see how to do CRUD operations against the MongoDB.<\/p>\n<h4>Creating documents<\/h4>\n<p>A document is an ordered set of keys with their associative values that\u2019s represented as a JSON:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar natalie_hershlag = {\r\n    &quot;name&quot;: &quot;Natalie Hershlag &quot;,\r\n    &quot;birthday&quot;: new Date(&quot;9\/6\/1981&quot;),\r\n    &quot;awards&quot;: &#x5B;&quot;V for Vendetta&quot;, &quot;Black Swan&quot;]\r\n};\r\n<\/pre>\n<p>Now, you can easily insert this document into actresses\u2019 collection:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.insert(natalie_hershlag);\r\n<\/pre>\n<p>Congratulations! You have created a new <b>collection<\/b> in your test database named actresses which contain a single <b>document<\/b>.<\/p>\n<p>You can verify that using the find command:<\/p>\n<p><code><br \/>\n> db.actresses.find();<br \/>\n{<br \/>\n    \"_id\": ObjectId(\"4d6a3e0e7747000000005ac8\"),<br \/>\n    \"name\": \"Natalie Hershlag \",<br \/>\n    \"birthday\": \"Sun Sep 06 1981 00:00:00 GMT+0430 (Iran Daylight Time)\",<br \/>\n    \"awards\": [\"V for Vendetta\", \"Black Swan\"]<br \/>\n}<\/code><\/p>\n<p>Well, you see a new property named <b>_id<\/b> that was not part of the original document is created automatically. The truth is that every document has a unique identity across a given collection so that the document can be uniquely identified. The default id uses the <b>ObjectId<\/b> to generate a 12-byte value consisting of a 4-byte timestamp (seconds since epoch), a 3-byte machine id, a 2-byte process id, and a 3-byte counter. For more information, please consult BSON ObjectID specification found <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Object+IDs\">here<\/a>.<\/p>\n<p>Let\u2019s add 2 more actresses to the collection:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.insert({ &quot;name&quot;: &quot;Megan Fox&quot;, &quot;birthday&quot;: new Date(&quot;16\/5\/1986&quot;), &quot;height&quot;: 1.63 });\r\ndb.actresses.insert({ &quot;name&quot;: &quot;Hayden Panettiere&quot;, &quot;birthday&quot;: new Date(&quot;21\/9\/1989&quot;) });\r\n<\/pre>\n<p>Please note that two latter documents don\u2019t have the same exact properties Natalie\u2019s document had. This means that the document shapes don\u2019t matter when working with MongoDB.<\/p>\n<h4>Reading documents<\/h4>\n<p>You have already learned how to read a document using the find method. The find method returns a database cursor that can be further used to limit, sort and skip number of given results. I believe this can be learned best by some examples.<\/p>\n<p><b>Example 1 \u2013 Find Natalie Hershlag\u2019s document<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.find({ &quot;name&quot;: &quot;Natalie Hershlag&quot; });\r\n<\/pre>\n<p><b>Example 2 \u2013 Find those actresses who have their height missing<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.find({ &quot;height&quot;: { &quot;$exists&quot;: false} });\r\n<\/pre>\n<p><b>Example 3 \u2013 Find those actresses who are at least 27 years old (at the time of this writing, albeit!)<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.find({ &quot;birthday&quot;: { &quot;$lt&quot;: new Date(&quot;1\/1\/1984&quot;)} });\r\n<\/pre>\n<p><b>Example 4 \u2013 Find award winning actresses of Black Swan film<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.find({ &quot;awards&quot;: { &quot;$in&quot;: &#x5B;&quot;Black Swan&quot;]} }); \r\n<\/pre>\n<p>The most important thing in the above mentioned queries is that they all return the entire document. Suppose that we want to retrieve just the actresses\u2019 names. This is where the second parameter comes into play. For example, let\u2019s find the actress name of the award winning Black Swan film:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.find({ &quot;awards&quot;: { &quot;$in&quot;: &#x5B;&quot;Black Swan&quot;]} }, { &quot;name&quot;: 1 });\r\n<\/pre>\n<p>Here, we ask specifically to return the name field. Please note that the _id field is always returned, regardless of what you pass in the second parameter.<\/p>\n<p>You have probably noticed $in, $lt and $exists operators in the examples above. They are special tokens used to indicate different criteria. &#8220;$in&#8221; operator tests whether a value is in an array of possible matches. &#8220;$lt&#8221; operator makes sure that a value is less than a given value, and $exists checks for existence of a field. There are multiple operators all <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Advanced+Queries\">listed here<\/a>.<\/p>\n<h4>Updating documents<\/h4>\n<p>In general, there are three common ways to manage concurrency in a database:<\/p>\n<ol>\n<li><b>Pessimistic concurrency control<\/b>: A record is unavailable to users from the time it\u2019s fetched until it\u2019s updated.<\/li>\n<li><b>Optimistic concurrency control<\/b>: A record is unavailable to users only when it\u2019s being actually updated.<\/li>\n<li><b>Last in wins<\/b>: A record is simply written out, potentially overwriting any changes made by other users.<\/li>\n<\/ol>\n<p>MongoDB follows the &#8220;Last in wins&#8221; model. This means that if two updates happen at the same time, the one who riches the server first will write the data. The next update will actually overwrite the previously updated document.<\/p>\n<p>To update a document, you could simply use the update method. The signature of this method follows:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.collection.update(criteria, objNew, upsert, multi);\r\n<\/pre>\n<p>Where criteria is a query document which locates the record to update, objNew is either the new document which describes the changes or $ operators which manipulate the object, upsert is a flag that says whether the document should be inserted if it doesn\u2019t exist, and multi which indicates if the entire documents matching criteria should be updated.<\/p>\n<p>To understand this, let\u2019s bring up some examples again.<\/p>\n<p><b>Example 1 \u2013 Modify Natalie Hershlag\u2019s name to Natalie Portman<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.update({ &quot;name&quot;: &quot;Natalie Hershlag&quot; }, { &quot;name&quot;: &quot;Natalie Portman&quot; });\r\n<\/pre>\n<p>As we\u2019ve already said, the second parameter, objNew, is the new document. Therefore, the above update command overwrites the previous one, causing the birthday, and her awards to lose.<\/p>\n<p><b>Example 2 \u2013 Insert Natalie Portman\u2019s birthday &#038; her awards to her document<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.update({ &quot;name&quot;: &quot;Natalie Portman&quot; }, { &quot;$set&quot;: { &quot;birthday&quot;: new Date(&quot;9\/6\/1981&quot;), &quot;awards&quot;: &#x5B;&quot;V for Vendetta&quot;, &quot;Black Swan&quot;]} });\r\n<\/pre>\n<p>Please note how we\u2019ve used the $set operator to set required fields. So this time, her name won\u2019t be touched. You can verify this by executing the following command:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.find({ &quot;name&quot;: &quot;Natalie Portman&quot; });\r\n<\/pre>\n<p><b>Example 3 \u2013 Insert Natalie Portman\u2019s award winning film &#8220;Where the heart is&#8221; to her awards<\/b><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.update({ &quot;name&quot;: &quot;Natalie Portman&quot; }, { &quot;$push&quot;: { &quot;awards&quot;: &quot;Where the heart is&quot;} });\r\n<\/pre>\n<p>The $push operator pushes a given value into an array.<br \/>\nThere are several other operators all listed here. Please consult the mentioned URL to learn more.<\/p>\n<h4>Removing documents<\/h4>\n<p>You can use the remove method to remove a document from a collection. It\u2019s gets a query document as its first parameter (just like the find method). If the query document is empty, then the entire documents will be removed from the given collection, e.g. db.actresses.remove({}) removes the entire actresses from the collection. However, if this is what you really want, it\u2019s always better to drop the entire collection:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndb.actresses.drop();\r\n<\/pre>\n<p>Well, I just tried to show you what the heck MongoDB is and how it works while trying not to mess with the little nifty things. There is tons of information about how to use all the features of MongoDB out there (see the references section of this article). It\u2019s now all up to you to learn those features and give NoSQL databases (an in particular, MongoDB) a try. The rest of the article, however, is dedicated to use MongoDB in a .NET application.<\/p>\n<h4>Using MongoDB in a .NET application (C#)<\/h4>\n<p>To start, let\u2019s <a href=\"https:\/\/github.com\/mongodb\/mongo-csharp-driver\/downloads\">download the CSharp Driver<\/a> (989KB). Get the MSI version and install it to the folder of your choice. Create a console application in C#, and add both assemblies found at the installed directory to the project references, say, MongoDB.Bson.dll and MongoDB.Driver.dll. (You also need to add at least two namespaces to the .cs files: MongoDB.Bson and MongoDB.Driver).<\/p>\n<p>Now let\u2019s connect to MongoDB server and retrieve the entire actresses\u2019 documents. To do so, we need to create a connection string as follows:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nstring connectionString = &quot;mongodb:\/\/localhost&quot;;\r\nMongoServer server = MongoServer.Create(connectionString);\r\n<\/pre>\n<p>The MongoServer class is a thread-safe class that handles the database connectivity. It also uses a pool of connections to increase efficiency. The next step is to get the required database (in this example, we need to get the &#8220;test&#8221; database).<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nMongoDatabase testDb = server.GetDatabase(&quot;test&quot;);\r\n<\/pre>\n<p>The next step is to get the actresses collection. This is done using the GetCollection method of MongoDatabase class:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nMongoCollection&lt;BsonDocument&gt; actresses = testDb.GetCollection&lt;BsonDocument&gt;(&quot;actresses&quot;);\r\n<\/pre>\n<p>Please note that we have not yet queried any data yet. We need to say which document to retrieve (remember the first parameter of the find method). To do so, we need to create a QueryDocument:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nQueryDocument entireDocuments = new QueryDocument();\r\n<\/pre>\n<p>Now we have the ingredients, so let\u2019s use them to get the documents:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nforeach (BsonDocument actress in actresses.Find(entireDocuments))\r\n{\r\n    Console.WriteLine(&quot;Name: {0}&quot;, actress&#x5B;&quot;name&quot;].AsString);\r\n\r\n    DateTime? birthDay = actress&#x5B;&quot;birthday&quot;].AsNullableDateTime;\r\n    Console.WriteLine(&quot;Birthday: {0}&quot;, birthDay.HasValue ? birthDay.Value.ToShortDateString() : (object)&quot;N\/A&quot;);\r\n\r\n    Console.WriteLine(&quot;Height: {0}&quot;, actress.Contains(&quot;height&quot;) ? actress&#x5B;&quot;height&quot;].AsDouble : (object)&quot;N\/A&quot;);\r\n\r\n    if (actress.Contains(&quot;awards&quot;))\r\n    {\r\n        Console.WriteLine(&quot;Awards: &quot;);\r\n        foreach (string award in actress&#x5B;&quot;awards&quot;].AsBsonArray)\r\n            Console.WriteLine(&quot;t{0}&quot;, award);\r\n    }\r\n\r\n    Console.WriteLine();\r\n}\r\n<\/pre>\n<p>The above code says it all. However, it\u2019s not what we are intended to do in real-world applications. We usually would like to deal with type-safe classes that ensemble document properties altogether. So let\u2019s modify the above code.<\/p>\n<p>First, we need to create a new class, say, Actress:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class Actress\r\n{\r\n    public ObjectId _id { get; set; }\r\n    public string name { get; set; }\r\n    public DateTime? birthday { get; set; }\r\n    public double height { get; set; }\r\n    public string&#x5B;] awards { get; set; }\r\n}\r\n<\/pre>\n<p>Do you remember that each document has got a property named _id? That\u2019s where it comes from.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nMongoCollection&lt;Actress&gt; actresses = testDb.GetCollection&lt;Actress&gt;(&quot;actresses&quot;);\r\nforeach (Actress actress in actresses.Find(new QueryDocument()))\r\n{\r\n    Console.WriteLine(&quot;Name: {0}&quot;, actress.name);\r\n\r\n    DateTime? birthDay = actress.birthday;\r\n    Console.WriteLine(&quot;Birthday: {0}&quot;, birthDay.HasValue ? birthDay.Value.ToShortDateString() : (object)&quot;N\/A&quot;);\r\n\r\n    Console.WriteLine(&quot;Height: {0}&quot;, actress.height &gt; 0 ? actress.height : (object)&quot;N\/A&quot;);\r\n\r\n    if (actress.awards != null)\r\n    {\r\n        Console.WriteLine(&quot;Awards: &quot;);\r\n        foreach (string award in actress.awards)\r\n            Console.WriteLine(&quot;t{0}&quot;, award);\r\n    }\r\n\r\n    Console.WriteLine();\r\n}\r\n<\/pre>\n<p>This code is much more reasonable. Now, let\u2019s insert one of my favorite actresses to the collection to show how to create a new document. To do so, we need to create an object of Actress type:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nActress charlizeTheron = new Actress()\r\n{\r\n    name = &quot;Charlize Theron&quot;,\r\n    height = 1.77,\r\n    birthday = new DateTime(1975, 8, 7),\r\n    awards = new string&#x5B;] { &quot;Monster&quot; }\r\n};\r\n<\/pre>\n<p>All we need to do now is to insert the above object in the actresses collection:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nactresses.Insert&lt;Actress&gt;(charlizeTheron);\r\n<\/pre>\n<p>And we are done. Now, there are 4 actresses in the test database and hopefully you know how to verify that.<\/p>\n<h4>Wrapping up<\/h4>\n<p>NoSQL databases are set of databases that do not use SQL. Designing a system based on such databases requires you to forget the relational model and focus on your objects. However, remember that it\u2019s simply another database model! No more, no less.<\/p>\n<p>An important thing I haven\u2019t mentioned (on purpose) yet is that MongoDB can operate in two modes: safe and unsafe. In safe mode (which is the default behavior of MongoDB Shell), the client waits for the database response to make sure that the operation in hand is either completed or failed. This is done by calling the getLastError command right after executing a given operation. It is your responsibility to decide whether an operation can be done unsafe. It\u2019s all about the performance.<\/p>\n<h4>References<\/h4>\n<ul>\n<li><a href=\"http:\/\/www.mongodb.org\/\">The MongoDB\u2019s official web site<\/a><\/li>\n<li><a href=\"http:\/\/oreilly.com\/catalog\/0636920001096\">MongoDB: The Definitive Guide<\/a><\/li>\n<li><a href=\"http:\/\/oreilly.com\/catalog\/0636920010852\">Cassandra: The Definitive Guide<\/a><\/li>\n<li><a href=\"http:\/\/blog.oskarsson.nu\/2009\/06\/nosql-debrief.html\">NOSQL debrief<\/a><\/li>\n<\/ul>\n<!-- google_ad_section_end -->","protected":false},"excerpt":{"rendered":"<p>10 years ago we have had no social network service in such a scale we used to see these days. <a href=\"http:\/\/www.facebook.com\/\">Facebook<\/a>, for instance, has got more than 600 million active users who modify their personal profiles, exchange messages, play games and the like every single day. Consider the total committed transactions per second caused [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4,6,7],"tags":[],"class_list":["post-34","post","type-post","status-publish","format-standard","hentry","category-csharp","category-nosql","category-sql"],"_links":{"self":[{"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/posts\/34","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":2,"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"predecessor-version":[{"id":56,"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions\/56"}],"wp:attachment":[{"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mehdi.biz\/blog\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}