63

I've programmatically created a new document collection using the MongoDB C# driver.

At this point I want to create and build indexes programmatically. How can I do that?

i3arnon
  • 113,022
  • 33
  • 324
  • 344
Payedimaunt
  • 1,014
  • 2
  • 10
  • 23
  • possible duplicate of [Creating MongoDB Unique Key with C#](http://stackoverflow.com/questions/6218966/creating-mongodb-unique-key-with-c-sharp) – WiredPrairie Jul 23 '13 at 10:54

6 Answers6

82

Starting from v2.0 of the driver there's a new async-only API. The old API should no longer be used as it's a blocking facade over the new API and is deprecated.

The currently recommended way to create an index is by calling and awaiting CreateOneAsync with an IndexKeysDefinition you get by using Builders.IndexKeys:

static async Task CreateIndexAsync()
{
    var client = new MongoClient();
    var database = client.GetDatabase("HamsterSchool");
    var collection = database.GetCollection<Hamster>("Hamsters");
    var indexKeysDefinition = Builders<Hamster>.IndexKeys.Ascending(hamster => hamster.Name);
    await collection.Indexes.CreateOneAsync(new CreateIndexModel<Hamster>(indexKeysDefinition));
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • 2
    Quick question for the peanut gallery I am a big fan of the strongly typed lambdas in C# over magic strings elsewhere but the question becomes assume the Hamster object had an array of addresses (billing, physical, mailing, etc) and I also wanted to index by zip code. Unfortunately once you hit Builders.IndexKeys.Ascending(_ => _.Addresses.First().ZipCode) the index creates as if zip code was on the root class hamster. The documentation on docs.mongodb.com is sparse at best. – Buvy Sep 29 '16 at 21:32
  • So you should create index only once at application startup? – Davide Quaglio Oct 17 '18 at 11:33
  • @DavideQuaglio That's what I usually do. It's enough to only do it just once, but this guarantees idempotency. – i3arnon Oct 17 '18 at 16:31
  • Please also check https://stackoverflow.com/questions/51248295/mongodb-c-sharp-driver-create-index – bonzaster Jan 03 '19 at 10:54
46

you should use CreateIndex as EnsureIndex is marked obsolete for future compatibility with the next versions of MongoDB:

var client = new MongoClient("mongodb://localhost");
var db = client.GetServer().GetDatabase("db");
var collection = db.GetCollection<Hamster>("Hamsters");

collection.CreateIndex(IndexKeys<Hamster>.Ascending(_ => _.Name));
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • 1
    @PhilBarresi Do you mean drop the existing one and build a new one? Or simply build another index? Both do not happen. – i3arnon Jul 17 '14 at 19:15
  • 10
    Apparently I was wrong; it sends the command to build an index, but if the index is already built it will result in a no-op; my misunderstanding came from an error with a foreground index creation causing other createindex calls to become blocked, leading me to believe that they were rebuilding the index. Apologies all, I3arnon is right here. – Phil Barresi Jul 18 '14 at 05:37
  • CreateIndex seems to be marked obsolete in my code whereas EnsureIndex is not. Is this info definitely correct? It seems unlikely to me that they'd have switched which ones were obsoleted in a version update (so I can't believe its just that we are looking at different versions of the code). – Chris Dec 08 '14 at 12:20
  • 1
    @Chris I don't know what version are you using, but in the latest stable one `EnsureIndex` is obsolete. It's the same in the current version of the [source code on github](https://github.com/mongodb/mongo-csharp-driver/blob/master/src/MongoDB.Driver/MongoCollection.cs#L406) – i3arnon Dec 08 '14 at 13:28
  • 1
    @I3arnon: I'm on an older version, 1.8.3 from nuget, it seems. Still weird that they went from createIndex being obsolete in the version I have with EnsureIndex being recommended to the other way round. Thanks for taking the time to check, and indeed for pointing me at the github source. Very useful. – Chris Dec 08 '14 at 14:48
  • For what its worth this change seems to have been made in 1.9.0 - https://github.com/mongodb/mongo-csharp-driver/blob/master/Release%20Notes/Change%20Log%20v1.9.0-Driver.txt – Chris Dec 08 '14 at 14:57
  • I am using `collectionName.Indexes.CreateOne(Builders.IndexKeys.Ascending(doc => doc.Field));` with v2.2.4. – Marcello Jul 11 '16 at 20:36
41

The overload of CreateOneAsync in the currently accepted answer is now marked as obsolete with the message "Use CreateOneAsync with a CreateIndexModel instead." Here's how you do it:

static async Task CreateIndex(string connectionString)
{
    var client = new MongoClient(connectionString);
    var database = client.GetDatabase("HamsterSchool");
    var collection = database.GetCollection<Hamster>("Hamsters");
    var indexOptions = new CreateIndexOptions();
    var indexKeys = Builders<Hamster>.IndexKeys.Ascending(hamster => hamster.Name);
    var indexModel = new CreateIndexModel<Hamster>(indexKeys, indexOptions);
    await collection.Indexes.CreateOneAsync(indexModel);
}
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
15

Something like this should do:

var server = MongoServer.Create("mongodb://localhost");
var db = server.GetDatabase("myapp");

var users = db.GetCollection<User>("users");

users.EnsureIndex(new IndexKeysBuilder().Ascending("EmailAddress"));

Please see the following bits in the documentation:

Community
  • 1
  • 1
Derick
  • 35,169
  • 5
  • 76
  • 99
4

There is an entire area on Indexing under the Definitions and Builders documentation page:

http://mongodb.github.io/mongo-csharp-driver/2.4/reference/driver/definitions/#index-keys

Example:

IndexKeysDefinition<MyModel> keys = "{ Reference: 1 }";
var indexModel = new CreateIndexModel<MyModel>(keys);
await _context.Indexes.CreateOneAsync(indexModel);
Craig
  • 390
  • 3
  • 13
  • 2
    It is worth nothing this references an older driver version. It has changed since. At the time of writing 2.13 is the most recent: http://mongodb.github.io/mongo-csharp-driver/2.13/reference/driver/definitions/#index-keys – Jack Jul 28 '21 at 11:07
4

the easiest way to create indexes in c# is by using the driver wrapper library MongoDB.Entities. here's an example of creating a text index:

    DB.Index<Author>()
      .Key(a => a.Name, Type.Text)
      .Key(a => a.Surname, Type.Text)
      .Create();

and to do a full-text search, you simply do:

    DB.SearchText<Author>("search term");

haven't seen anything else that makes it simpler than that.

Dĵ ΝιΓΞΗΛψΚ
  • 5,068
  • 3
  • 13
  • 26