using MongoDB.Driver; using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Linq.Expressions; using MongoDbGenericRepository.Models; using System.Linq; namespace MongoDbGenericRepository { /// /// The repository interface for managing indexes /// public interface IMongoDbCollectionIndexRepository { /// /// Create a text index on the given field. /// IndexCreationOptions can be supplied to further specify /// how the creation should be done. /// /// The type representing a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument; /// /// Create a text index on the given field. /// IndexCreationOptions can be supplied to further specify /// how the creation should be done. /// /// The type representing a Document. /// The type of the primary key for a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; /// /// Creates an index on the given field in ascending order /// /// The type representing a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument; /// /// Creates an index on the given field in ascending order /// /// The type representing a Document. /// The type of the primary key for a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; /// /// Creates an index on the given field in descending order /// /// The type representing a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// A string containing the result of the operation. Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument; /// /// Creates a hashed index on the given field. /// /// The type representing a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// A string containing the result of the operation. Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument; /// /// Creates a hashed index on the given field. /// /// The type representing a Document. /// The type of the primary key for a Document. /// The field we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; /// /// Creates a combined text index /// /// The type representing a Document. /// The fields we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument; /// /// Creates a combined text index /// /// The type representing a Document. /// The type of the primary key for a Document. /// The fields we want to index /// Options for creating an index.. /// An optional partition key /// The result of the create index operation. Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; /// /// Drops the index given a field name /// /// The type representing a Document. /// The name of the index /// An optional partition key Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument; /// /// Drops the index given a field name /// /// The type representing a Document. /// The type of the primary key for a Document. /// The name of the index /// An optional partition key Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; /// /// Returns the names of the indexes present on a collection. /// /// The type representing a Document. /// An optional partition key /// A list containing the names of the indexes on on the concerned collection. Task> GetIndexesNamesAsync(string partitionKey = null) where TDocument : IDocument; /// /// Returns the names of the indexes present on a collection. /// /// The type representing a Document. /// The type of the primary key for a Document. /// An optional partition key /// A list containing the names of the indexes on on the concerned collection. Task> GetIndexesNamesAsync(string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; } /// /// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation. /// Its constructor must be given a connection string and a database name. /// public abstract partial class BaseMongoRepository : ReadOnlyMongoRepository, IBaseMongoRepository { #region Index Management /// public async Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateTextIndexAsync(field, indexCreationOptions, partitionKey); } /// public async Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { return await HandlePartitioned(partitionKey).Indexes .CreateOneAsync( new CreateIndexModel( Builders.IndexKeys.Text(field), indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions) )); } /// public async Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateAscendingIndexAsync(field, indexCreationOptions, partitionKey); } /// public async Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { var collection = HandlePartitioned(partitionKey); var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); var indexKey = Builders.IndexKeys; return await collection.Indexes .CreateOneAsync( new CreateIndexModel(indexKey.Ascending(field), createOptions)); } /// public async Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateDescendingIndexAsync(field, indexCreationOptions, partitionKey); } /// public async Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { var collection = HandlePartitioned(partitionKey); var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); var indexKey = Builders.IndexKeys; return await collection.Indexes .CreateOneAsync( new CreateIndexModel(indexKey.Descending(field), createOptions)); } /// public async Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateHashedIndexAsync(field, indexCreationOptions, partitionKey); } /// public async Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { var collection = HandlePartitioned(partitionKey); var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); var indexKey = Builders.IndexKeys; return await collection.Indexes .CreateOneAsync( new CreateIndexModel(indexKey.Hashed(field), createOptions)); } /// public async Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateCombinedTextIndexAsync(fields, indexCreationOptions, partitionKey); } /// public async Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { var collection = HandlePartitioned(partitionKey); var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); var listOfDefs = new List>(); foreach (var field in fields) { listOfDefs.Add(Builders.IndexKeys.Text(field)); } return await collection.Indexes .CreateOneAsync(new CreateIndexModel(Builders.IndexKeys.Combine(listOfDefs), createOptions)); } /// public async Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument { await DropIndexAsync(indexName, partitionKey); } /// public async Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { await HandlePartitioned(partitionKey).Indexes.DropOneAsync(indexName); } /// public async Task> GetIndexesNamesAsync(string partitionKey = null) where TDocument : IDocument { return await GetIndexesNamesAsync(partitionKey); } /// public async Task> GetIndexesNamesAsync(string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { var indexCursor = await HandlePartitioned(partitionKey).Indexes.ListAsync(); var indexes = await indexCursor.ToListAsync(); return indexes.Select(e => e["name"].ToString()).ToList(); } #endregion Index Management private CreateIndexOptions MapIndexOptions(IndexCreationOptions indexCreationOptions) { return new CreateIndexOptions { Unique = indexCreationOptions.Unique, TextIndexVersion = indexCreationOptions.TextIndexVersion, SphereIndexVersion = indexCreationOptions.SphereIndexVersion, Sparse = indexCreationOptions.Sparse, Name = indexCreationOptions.Name, Min = indexCreationOptions.Min, Max = indexCreationOptions.Max, LanguageOverride = indexCreationOptions.LanguageOverride, ExpireAfter = indexCreationOptions.ExpireAfter, DefaultLanguage = indexCreationOptions.DefaultLanguage, BucketSize = indexCreationOptions.BucketSize, Bits = indexCreationOptions.Bits, Background = indexCreationOptions.Background, Version = indexCreationOptions.Version }; } } }