/// <summary> /// Call this method to finalize defining the index after setting the index keys and options. /// </summary> /// <param name="cancellation">An optional cancellation token</param> public async Task CreateAsync(CancellationToken cancellation = default) { if (Keys.Count == 0) { throw new ArgumentException("Please define keys before calling this method."); } var propNames = new HashSet <string>(); var keyDefs = new HashSet <IndexKeysDefinition <T> >(); var isTextIndex = false; foreach (var key in Keys) { string keyType = string.Empty; switch (key.Type) { case KeyType.Ascending: keyDefs.Add(Builders <T> .IndexKeys.Ascending(key.PropertyName)); keyType = "(Asc)"; break; case KeyType.Descending: keyDefs.Add(Builders <T> .IndexKeys.Descending(key.PropertyName)); keyType = "(Dsc)"; break; case KeyType.Geo2D: keyDefs.Add(Builders <T> .IndexKeys.Geo2D(key.PropertyName)); keyType = "(G2d)"; break; case KeyType.Geo2DSphere: keyDefs.Add(Builders <T> .IndexKeys.Geo2DSphere(key.PropertyName)); keyType = "(Gsp)"; break; case KeyType.GeoHaystack: keyDefs.Add(Builders <T> .IndexKeys.GeoHaystack(key.PropertyName)); keyType = "(Ghs)"; break; case KeyType.Hashed: keyDefs.Add(Builders <T> .IndexKeys.Hashed(key.PropertyName)); keyType = "(Hsh)"; break; case KeyType.Text: keyDefs.Add(Builders <T> .IndexKeys.Text(key.PropertyName)); isTextIndex = true; break; case KeyType.Wildcard: keyDefs.Add(Builders <T> .IndexKeys.Wildcard(key.PropertyName)); keyType = "(Wld)"; break; } propNames.Add(key.PropertyName + keyType); } if (string.IsNullOrEmpty(options.Name)) { if (isTextIndex) { options.Name = "[TEXT]"; } else { options.Name = string.Join(" | ", propNames); } } var model = new CreateIndexModel <T>( Builders <T> .IndexKeys.Combine(keyDefs), options); try { await DB.CreateIndexAsync(model, db, cancellation); } catch (MongoCommandException x) { if (x.Code == 85 || x.Code == 86) { await DB.DropIndexAsync <T>(options.Name, db, cancellation); await DB.CreateIndexAsync(model, db, cancellation); } else { throw; } } }
/// <summary> /// Call this method to finalize defining the index after setting the index keys and options. /// </summary> async public Task CreateAsync() { if (Keys.Count == 0) { throw new ArgumentException("Please define keys before calling this method."); } var propNames = new HashSet <string>(); var keyDefs = new HashSet <IndexKeysDefinition <T> >(); var isTextIndex = false; foreach (var key in Keys) { switch (key.Type) { case Type.Ascending: keyDefs.Add(Builders <T> .IndexKeys.Ascending(key.Property)); break; case Type.Descending: keyDefs.Add(Builders <T> .IndexKeys.Descending(key.Property)); break; case Type.Geo2D: keyDefs.Add(Builders <T> .IndexKeys.Geo2D(key.Property)); break; case Type.Geo2DSphere: keyDefs.Add(Builders <T> .IndexKeys.Geo2DSphere(key.Property)); break; case Type.GeoHaystack: keyDefs.Add(Builders <T> .IndexKeys.GeoHaystack(key.Property)); break; case Type.Hashed: keyDefs.Add(Builders <T> .IndexKeys.Hashed(key.Property)); break; case Type.Text: keyDefs.Add(Builders <T> .IndexKeys.Text(key.Property)); isTextIndex = true; break; } var member = key.Property.Body as MemberExpression; if (member == null) { member = (key.Property.Body as UnaryExpression)?.Operand as MemberExpression; } if (member == null) { throw new ArgumentException("Unable to get property name"); } propNames.Add(member.Member.Name); } if (string.IsNullOrEmpty(_options.Name)) { _options.Name = DB.GetCollectionName <T>(); if (isTextIndex) { _options.Name = $"{_options.Name}[TEXT]"; } else { _options.Name = $"{_options.Name}[{string.Join("-", propNames)}]"; } } var model = new CreateIndexModel <T>( Builders <T> .IndexKeys.Combine(keyDefs), _options.ToCreateIndexOptions()); try { await DB.CreateIndexAsync <T>(model); } catch (MongoCommandException x) { if (x.Code == 85 || x.Code == 86) { await DB.DropIndexAsync <T>(_options.Name); await DB.CreateIndexAsync <T>(model); } else { throw x; } } }