Skip to content

askazakov/mongo-csharp-declarative-indexes

Repository files navigation

NuGet Status

MongoDB.DeclarativeIndexes - it is a small helper for declarative description of indexes for MongoDB. Just list desired indexes and IndexEnsurer creates missing indexes and drops excess ones.

IndexEnsurer ensurer = ...
ensurer.Ensure(new CollectionIndexes("collection_name",
                                     new Index(keys: new Key("field_name", IndexType.Ascending)),
                                     new Index(keys: new[] // compound index
                                     {
                                         new Key("first_field", IndexType.Ascending),
                                         new Key("second_field", IndexType.Descending)
                                     })),
               new CollectionIndexes("another_collection",
                                     new Index(keys: new Key("a", IndexType.Ascending))));

You don't need write explicit CreateOne, CreateMany or DropOne anymore.

IndexEnsurer also provides Begin method for two-step process. This is useful in case when you want do something between drop excess indexes and create new ones – for example you could drop non-unique index, normalize db documents and then create unique index:

// there is collection with non-unique index

// declare unique indexes
var continuation = ensurer.Begin(new[]
{
    new CollectionIndexes("collection",
                          new Index(keys: new Key("field", IndexType.Ascending),
                                    unique: true))
});

// do some stuff with 'collection'

// and continue with indexes
continuation.Continue();

EnsurerContinuation can rollback if something goes wrong and you want to abort index dropping:

var continuation = ensurer.Begin(new[]
{
    new CollectionIndexes("collection",
                          new Index(keys: new Key("field", IndexType.Ascending),
                                    unique: true))
});
try {
    // do some stuff 
}
catch (Exception)
{
    continuation.Rollback();
    throw
}

continuation.Continue();

To avoid dependency on MongoDB.Driver (or any other mongodb library) MongoDB.DeclarativeIndexes uses IoC – IndexEnsurer takes IDatabase abstraction as constructor argument:

public interface IDatabase
{
    IEnumerable<string> ListCollectionNames();
    
    IEnumerable<Dictionary<string, object>> ListIndexes(string collectionName);

    void CreateManyIndexes(string collectionName, IEnumerable<Index> indexes);

    void DropOneIndex(string collectionName, string indexName);
}

So you need to implement it with real mongodb client:

using MongoDB.Bson;  // from MongoDB.Driver
using MongoDB.Driver;

...

class Adapter : IDatabase
{
    private readonly IMongoDatabase _mongoDatabase;

    public Adapter(IMongoDatabase mongoDatabase)
    {
        _mongoDatabase = mongoDatabase;
    }

    public void CreateManyIndexes(string collectionName, IEnumerable<Index> indexes)
    {
        var collection = _mongoDatabase.GetCollection<BsonDocument>(collectionName);
        var createIndexModels =
            indexes.Select(i => new CreateIndexModel<BsonDocument>(KeysDefinitionFrom(i), OptionsFrom(i)));
        collection.Indexes.CreateMany(createIndexModels);
    }

    public IEnumerable<Dictionary<string, object>> ListIndexes(string collectionName)
    {
        var collection = _mongoDatabase.GetCollection<BsonDocument>(collectionName);
        return collection.Indexes.List().ToEnumerable().Select(index => index.ToDictionary());
    }

    public IEnumerable<string> ListCollectionNames()
    {
        return _mongoDatabase.ListCollectionNames().ToEnumerable();
    }

    public void DropOneIndex(string collectionName, string indexName)
    {
        _mongoDatabase.GetCollection<BsonDocument>(collectionName).Indexes.DropOne(indexName);
    }

    private static CreateIndexOptions OptionsFrom(Index index)
    {
        return new CreateIndexOptions {Unique = index.Unique};
    }

    private static IndexKeysDefinition<BsonDocument> KeysDefinitionFrom(Index index)
    {
        return new BsonDocumentIndexKeysDefinition<BsonDocument>(new BsonDocument(index.ToDb()));
    }
}

...

    var client = new MongoClient("mongodb://localhost:27017");
    var database = client.GetDatabase("test");

    var adapter = new Adapter(database);

    var ensurer = new IndexEnsurer(adapter);

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages