Setup and Configuration
The first thing todo is to download MongoDB. I chose to do it on my Windows 10 machine rather than use one of my Virtual Machines, though I may do it again later on Linux. You can run MongoDb in the cloud, which makes a lot of sense if you are a business, but I wanted a local copy to play with. Here is the link for the download:
https://www.mongodb.com/download-center?jmp=hero#community
The windows download has an installer, and is easy to install. It does require some additional configuration. For one thing, you must create a couple of new directories for the data.
C:\data C:\data\db C:\data\log
To start the MongoDB server. Open a command prompt (or powershell) and navigate to the folder where the Mongod.exe file is. On my machine it is at:
C:\Program Files\MongoDB\Server\3.2\bin
Run Mongod.exe.
After you run it, you will get all sorts of status information. The last line will say that it is waiting for connections.
Using the Mongo Command Shell
Leave this window open. Start another command window. Navigate to the same directory and run mongo.exe. This is the commmand shell for the server.
"test" is your default database.
I am going to perform a few basic tasks in the shell such as creating a database, creating a collection (table), adding records, adding indexes, and retrieving records. I figured out the commands mostly by using the MongoDB documentation which can be found starting at:
https://docs.mongodb.com/manual/
To create a new database, all you have to do is say "use <:newDatabase>" (put in the name of your new database.). If the database exists, it will switch context to that database. If it doesn't it will create the database and switch contexts. Let's create a database called "books."
Mongodb's equivalent to tables are called collections. You can create a new collection much the same way that you created a new database, by simply calling on the collection. If it doesn't exit, mongodb will create it. Collections, unlike tables, are schema-less. That means you do not predefine the columns and their data types. In fact the various data objects can be structured differently, though it is best if they are at least similar. If you need a more defined schema you can create one with the explicit createCollection() command. We might look into that later. For now, we will just use the implicit collection creation with the following command. We will do it with the find() method which will return all records in a collection. In our case it will return nothing because we have not yet added any records.
db.bookCollection.find()
Inserting
Now let's add a record. Records are structured as JSON (JavaScript Object Notation). JSON basically consists of name value pairs separated by a colon. Here is our first Book example:
{ ISBN : "9780062371058", title : "Neverwhere", author : "Neil Gaiman", year : "2015", publisher : "Morrow", description : "A young man, Richard Mayhew, helps an injured girl on a London street one afternoon, a act of kindness that leads him into a magical world he never knew existed, a world that lives below London and in its shadows." }
A couple of notes: in a relational database, Author would be broken into a separate table, and because a book can have multiple authors, a linking table would be created to join the Author and Book tables. MongoDb doesn't support joins as such, though it is possible to repeat the key of one record in another record, in effect creating a foreign key. It requires two queries however to get the two related records. Mongodb documentation recommends doing this when otherwise there would be a lot of redundancy. There are no referential integrity checks to force the relation to be accurate. It is entirely up to the users to make sure the reference keys are accurate.
To enter this we can use the insert() command. (Commands by the way are case sensitive.)
If we run the find now it should return our new record.
Note that Mongodb created an "_id" field for the record and gave it a unique ObjectID. This is what you would use for any references in another collection.
Let's create a second record:
{ ISBN : "0231079893", title : "What is Philosophy?", author : ["Gilles Deleuze","Felix Guattari"], translator : ["Hugh Tomlinson", "Graham Burchell"], year : "1994", publisher : "Columbia University Press", description : "A surprisingly profound discussion of the nature of concepts, and the nature of the philosophical endeavor itself." }
Notice that the structure of this record differs in some aspects from the first one. The author field is now an array of authors. There is also a new field "translator" which is also an array. Part of having no schema is that records can differ from each other.
Query
We looked at find(), but let's try to write a query that returns a specific record.
First we will look for specific literal values. Here is a query for the book with the title "Neverwhere"
db.bookCollection.find({title : "Neverwhere"})
This is fairly intuitive. You just enter the name value pair and it returns any matches. But what about those arrays in the second record. How would I search for a book by "Gilles Deleuze?" Thankfully all you have to do is list the author's name and if one value in the array matches it will return the record. Here are examples for "Deleuze" and the second translator "Burchell."
Gilles Deleuze:
Graham Burchell:
You can also query with comparative operators such as > and <. Here is a query for a all the books with a year greater than "2000".
db.bookCollection.find({year : {"$gt: "2000"}})
Text Index
It would be nice to query the description of the book without having to match the entire text. This is possible if you create a text index on the description field. The text index behaves very much like the full text index in Sql Server. It allows you to look for words and phrases in an indexed field.
To create an index you just use the createIndex() function. You specify the field and the type of index--"text.
db.bookCollection.createIndex({description : "text"})
Now let's see if we can search for a word in the description. Let's search for "London" which is in the Neverwhere description. The code for this is:
db.bookCollection.find({$text : {$search : "London"}})
Now let's search for the phrase "nature of concepts."
A couple Administrative Commands
Finally I am going to show a couple of administrative commands. One to show all the indexes on a table, and the other to get all the databases.
To get all the indexes on a table you can use the following command:
db.bookCollection.getIndexes()
Note that there are two indexes. The first is the clustered index put on the automatically generated key. The second is the text index we created.
Next, this is the command that returns all databases on the server:
db.adminCommand({listDatabases : 1 })
I have more databases because I have been playing with this for a while.
There is a lot more to cover in future blogs. For one thing, we can look at how to do bulk inserts and more sophisticated queries. We will also create a database with multiple collections, including some collections which reference each other. There is the matter of setting up security. I will also create some interfaces to mongodb in languages such as C#, Java and Python. I may also try to integrate it with NodeJs. But this is enough for now.
No comments:
Post a Comment