First, let's make it clear NoSQL is not replacement for SQL, it is alternative. Both have their uses and you should carefully consider which one to use. Sometimes it might make sense to use both at same time.
There are few types of NoSQL databases, each type stores data differently and has different purpose. For example, key-value NoSQL databases store data in key value pairs. Key-values databases are mostly used for cache. Redis is one of most used key-value database. There are few other types and you should check them out to see what can help you.
MongoDB is open source document database which provides high performance, high availability and automatic scaling. MongoDB stores data in BSON documents - they are something like rows in SQL. BSON (Binary JSON) is very similar to JSON, but it contains extensions which allow representation of data that are not part of JSON spec, like date (for more info about BSON visit www.bson.org
). Because documents are JSON-like this makes working and conversion with them simple, so simple that you don’t even need ORM. MongoDB requires each document to have id field, named _id. If you omit id field MongoDB will add it for you and generate it. By default, MongoDB uses ObjectID to generate ids. This ids are 12 byte hexadecimal strings. To learn more about them visit https://docs.mongodb.com/manual/reference/method/ObjectId/
. In case this doesn’t suite you, don’t worry, you can use something else for ids. You can use strings, integers, in fact anything but arrays. There is just one catch, if you use anything other than ObjectID you will have to generate this manually.
There are some document limitations which you should keep in mind. Document has maximum size of 16 MB. Also field name _id is reserved. Field names can not start with "$" sign, contain "." character nor null character.
While SQL databases store data in tables, MongoDB stores them in collections. There is one major difference between them and that is one of the greatest benefits of MongoDB. When using SQL table, you must predefine columns and their types. This is great when you have data which structure doesn’t change often. In case when data changes structure often, that leads to lot of extra work to update database. In MongoDB collections don’t enforce constraints. What does that mean? It means that collection can hold documents which don’t have the same structure. In fact, each document in collection could have the unique structure, although that isn’t very useful. This is great when you have a model which evolves constantly, as you only have to update your model in code. You don’t have to worry about your database, as it will simply store new fields without any extra work (you might need a bit of extra work to setup default values for new fields).
Now we know how MongoDB stores data, but question is how this affects your way of storing data. When you use SQL you always normalize data, and this is kind of a problem for SQL. By that I mean that you never store your model as an object in database, you store it as a bunch of rows in bunch of tables. You also must have some way to connect data and you can recreate object, so you add foreign keys to table…
But what about MongoDB? Well you should deformalize data. Just store your whole object as document. This is helpful because you don’t have a hard time collecting all data to reassemble your object, also it makes querying easier and faster. Due to limitation of document size (it can’t be larger than 16MB), this approach might be a problem. But don’t worry MongoDB supports joins now, so if you really need to, you can normalize data. As of version 3.2 MongoDB added support for left-outer joins. You can normalize data without it, but it would require you to manually map data.
That was a lot of theory, so let’s jump into small example to see how this works in practice. First, we will have to install MongoDB. You can find installation instructions here: https://docs.mongodb.com/manual/installation/
. To make our work easier, MongoDB has official drivers for most popular programming languages. You can find list of all supported languages here: https://docs.mongodb.com/ecosystem/drivers/
. I'll create example with C#.
The first thing you want to do is install MongoDB driver. Search for MongoDB.Driver, there will be few of them available but we will use one made by MongoDb. I will be using version 2.5.0. and create simple Todo application. We will have to create a model to represent Todo.
Property Id has two attributes BsonID and BsonRepresentation. BsonId specifies that field is used for _id and BsonRepresentation specifies which type of field will be used. We’ll use ObjectId for _id so that MongoDB takes care of generating unique ids. TodoMetaData class doesn’t need id property as it will be embedded into Todo document. Technically there is no need for that class, but I’ve added it, so we can see how MongoDB stores embedded objects. Now when we have a model, we need a way to store data into MongoDB.
We need instance of MongoClient to get access to database. To get database we need to call method GetDatabase and pass the name of database. In case that database doesn’t exist, it will be created. To fetch collection, we have to call GetCollection method on database object. With generics we can specify which class will be used as default document. Now we have everything we need to store some data into our database, so let’s do that.
This is pretty straight forward. We create TodoContext, then create our Todo object and just call InsertOne on Todo collection. There are two ways we can check what is stored in our database: we can use command line and use mongo.exe or we can install MongoDB Compass. I’d suggest you check out command line on your own, there are plenty of resources online which can help you with that. I will use MongoDB compass for this example.
You can download it here: https://www.mongodb.com/products/compass
. Start the application and use default values. Select your database, find collection (for me database is mydb2 and collection is Todos) and you will see all documents you stored into this collection.
Now that we have stored data, we need a way to fetch that data, maybe even filter it. Fortunately, that isn’t a complicated task .
To filter documents we have to create a BSONDocument which will be used as filter. To make this easier MongoDB has Builders class. This class help us create filter object. Eq is equals operator in MongoDB. So this query would return us a list of Todos which are not done. There are a lot of operators for querying available. You can find them here https://docs.mongodb.com/manual/reference/operator/query/
All examples here used POCOs to work with MongoDB. If you want, you don’t have to use them at all. Driver contains BSONDocument class which can be used to achieve all of this without POCO (in examples all POCOs were serialized to BSONDocument).