Introduction to MongoDb with .NET part 39: working with indexes in the MongoDb .NET driver

Introduction

In the previous post we went through a couple of diagnostics tools available in MongoDb. We mentioned the default logging tool which automatically logs all queries that took more than 100ms to complete. Then we looked at 3 tools that provide more details about what is going on in MongoDb: the profiler, mongotop and mongostat. They are great tools especially when we’re trying to optimise our queries. They also help debug our application by looking at the actual queries executed in the database.

This is the final post dedicated to indexing and performance in MongoDb. We’ll look at how to work with indexes in the MongoDb .NET driver.

Indexes in the MongoDb driver

Normally we work with indexes directly in the mongo shell. However, if you prefer to take advantage of C# and Visual Studio then the .NET driver offers a number of entry points to indexing.

The gateway to the indexing facilities is the Indexes property available on a collection which returns an index manager. Let’s start with listing the indexes available on restaurants collections:

ModelContext modelContext = ModelContext.Create(new ConfigFileConfigurationRepository(), new AppConfigConnectionStringRepository());
var restaurantsIndexManager = modelContext.Restaurants.Indexes;

var restaurantsIndexList = restaurantsIndexManager.List();
while (restaurantsIndexList.MoveNext())
{
	var currentIndex = restaurantsIndexList.Current;
	foreach (var doc in currentIndex)
	{
		var docNames = doc.Names;
		foreach (string name in docNames)
		{
			var value = doc.GetValue(name);
			Debug.WriteLine(string.Concat(name, ": ", value));
		}
	}
}

The above code will print the following in the debug window:

v: 1
key: { “_id” : 1 }
name: _id_
ns: model.restaurants
v: 1
key: { “borough” : 1.0, “cuisine” : 1.0 }
name: borough_1_cuisine_1
ns: model.restaurants
v: 1
key: { “grades.grade” : 1.0, “grades.score” : 1.0 }
name: grades.grade_1_grades.score_1
ns: model.restaurants

…which corresponds to the output produced by the getIndexes() command in the mongo shell:

[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "model.restaurants"
        },
        {
                "v" : 1,
                "key" : {
                        "borough" : 1,
                        "cuisine" : 1
                },
                "name" : "borough_1_cuisine_1",
                "ns" : "model.restaurants"
        },
        {
                "v" : 1,
                "key" : {
                        "grades.grade" : 1,
                        "grades.score" : 1
                },
                "name" : "grades.grade_1_grades.score_1",
                "ns" : "model.restaurants"
        }
]

Index creation

The index manager offers 4 methods for index creation:

  • CreateOne
  • CreateOneAsync
  • CreateMany
  • CreateManyAsync

We saw a lot of similar examples before when we discussed CRUD operations. There’s a function to create one or many indexes, and they have their asynchronous counterparts as well for awaitable operations. We’ll look at an example with the CreateOne function.

Do you recall definitions such as the filter and sort definitions? There are index key definitions that can be built using the index keys definition builder. The IndexKeys property of the static Builders class offers the entry point into creating index keys definitions.

As you start typing…

Builders<RestaurantDb>.IndexKeys.

…in Visual Studio then you’ll see a couple of familiar methods like Ascending, Descending and Text. There are also some more specialised index types that we haven’t looked at in this series, they are related to geo-spatial data types. The Combine method combines two or more indexes into one compound index. The Create methods also accept and CreateIndexOptions object where you can specify the options we saw before, like the index name, whether it’s sparse etc. Here’s a simple example that creates an index on the restaurant_id field of the restaurants collection:

ModelContext modelContext = ModelContext.Create(new ConfigFileConfigurationRepository(), new AppConfigConnectionStringRepository());
var restaurantsIndexManager = modelContext.Restaurants.Indexes;
var restaurantIndexDefinition = Builders<RestaurantDb>.IndexKeys.Ascending(r => r.Id);
string result = restaurantsIndexManager.CreateOne(restaurantIndexDefinition, new CreateIndexOptions() { Name = "RestaurantIdIndexAsc", Background = true });

The CreateOne function returns the name of the index, in this case “RestaurantIdIndexAsc”.

Here’s our index in the mongo shell:

{
                "v" : 1,
                "key" : {
                        "restaurant_id" : 1
                },
                "name" : "RestaurantIndexAsc",
                "ns" : "model.restaurants",
                "background" : true
}

Dropping an index

We can easily drop an index by its name:

ModelContext modelContext = ModelContext.Create(new ConfigFileConfigurationRepository(), new AppConfigConnectionStringRepository());
var restaurantsIndexManager = modelContext.Restaurants.Indexes;
restaurantsIndexManager.DropOne("RestaurantIdIndexAsc");

If the index is not found by name then we get an exception:

Command dropIndexes failed: index not found with name [nosuchindex].

DropOne has an async counterpart. The DropAll and DropAllAsync methods remove all the indexes from the collection.

Read the next part here.

You can view all posts related to data storage on this blog here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: