Recently, I’ve been using MongoDB every day. Before this, I was used SQL server almost exclusively. I decided to use MongoDB over SQL for my most recent project and it has a bit of a learning curve. Here are a couple MongoDB concepts that took me a little bit to understand and get working within .NET. My project is running .NET Core under framework version 4.6.1.
Configuring as a Windows Service
When MongoDB is installed, it just lays down the binaries and you are tasked with installing the service.
First, you need to create a configuration file. It that contains the location of your log and DB.
Next, there is a command line argument you can provider mongod.exe with to install the service.
There was a recent string of reports that many public facing MongoDB servers were left completely insecure and configured with their default port. You can easily add an admin user account by running the MongoDB server using mongod.exe and then executing the below command line.
You’ll then need to include the following in your MongoDB config file after restarting your service.
MongoDB has its own ID format; ObjectID. When I was developing my API, I wanted to abstract any MongoDB specific types from the rest of my implementation so settled on GUIDs instead of ObjectIDs. 3T has a great article on this. To use GUIDs for your data model, you need to map the ID to ID generator. I did so in a static constructor to the repository class I’m using for our repository pattern.
You’ll need to do this for each type.
Filtering, Sorting and Paging
All the neat stuff is done using the Builders class. It’s easiest to create a variable for each of the components of the query that you want to use and then aggregate them together. What’s really slick is that the folks at MongoDB implemented the & and | operators on the Builders classes to create complex queries. I thought it was a ingenious way to take advantage of those.
To return all items in a collection, you can use an empty filter.
Just like many operations in MongoDB, updates are done using JSON documents. Using the C# driver, you’ll need to produce a document that has an outer element, named $set, that contains the actual properties you wish to update.
MongoDB supports upserts. So rather than having to query for the existence of a document and then issue another query to update or create it, you can do it in a single query. Getting the syntax right is a bit tricky so I list my working solution below.
Although MongoDB doesn’t really support JOINs, it does have the concept of aggregates. Below is an example of using the Unwind and Match steps of the aggregate pipeline. Unwind takes each item of a child array and returns an instance of the parent document with the selected property changed to each item in the child array.
For example, if we unwind the following document on the ObjectsChanged property.
It would result in an array of documents like this.
The great thing about the aggregate pipeline is that you can chain these operations together. So now I could add a Match step to filter out only the IDs I’m interested. The C# code would look something like this.
The aggregate pipeline also supports things like grouping and counting.
Cursors are returned by Find operations. They have a lot of the same features of an IEnumerable but aren’t quite the same thing. For my API interface, I again wanted to abstract away MongoDB types, so I built interfaces that exposed IEnumerables. A couple things to note.
Cursors can only be enumerated once
ReSharper will give you a warning about this when developing against IEnumerables but with the cursor type returned by the MongoDB C# driver, IASyncCursor, if you enumerate them more than once, an exception will be thrown. With EF, I believe the query would just be run again.
Cursors can be exposed as IEnumerables
There is a handy method on the IAsyncCursor class that lets you convert it to an IEnumerable. It’s aptly named ToEnumerable().
Have any tips or tricks that you use when developing for MongoDB using .NET?
I’m totally digging MongoChef right now as a client to MongoDB. It’s free for non-commercial use.