public string createIndex(object keys, object options) { BsonDocumentIndexKeysDefinition <BsonDocument> keysDefinitions = new BsonDocumentIndexKeysDefinition <BsonDocument>(keys.ToBsonDocument()); CreateIndexOptions createIndexOptions = new CreateIndexOptions(); return(this._collection.Indexes.CreateOne(keysDefinitions, createIndexOptions)); }
public bool Execute(IMongoDatabase database, MongoStorageOptions storageOptions, IMongoMigrationBag migrationBag) { var db = database.GetCollection <BsonDocument>($@"{storageOptions.Prefix}.statedata"); var index = new BsonDocumentIndexKeysDefinition <BsonDocument>(new BsonDocument("Key", 1)); db.Indexes.CreateOne(index); return(true); }
// private methods private CreateIndexModel <BsonDocument> CreateCreateIndexModel() { var keysDefinition = new BsonDocumentIndexKeysDefinition <BsonDocument>(_keys); var options = new CreateIndexOptions { Name = _name }; return(new CreateIndexModel <BsonDocument>(keysDefinition, options)); }
private static void CreateJobIndex(IMongoCollection <BsonDocument> collection) { var index = new BsonDocumentIndexKeysDefinition <BsonDocument>(new BsonDocument("JobId", -1)); var options = new CreateIndexOptions { Name = "JobId", }; collection.Indexes.CreateOne(index, options); }
/// <summary> /// Backups the collection in database identified by collectionName. /// </summary> /// <param name="database">Referance to the mongo database.</param> /// <param name="collectionName">The name of the collection to backup.</param> /// <param name="backupCollectionName">Tha name of the backup collection.</param> protected virtual void BackupCollection(IMongoDatabase database, string collectionName, string backupCollectionName) { var aggregate = new BsonDocument(new Dictionary <string, object> { { "aggregate", collectionName }, { "pipeline", new [] { new Dictionary <string, object> { { "$match", new BsonDocument() } }, new Dictionary <string, object> { { "$out", backupCollectionName } } } }, { "allowDiskUse", true }, { // As of MongoDB 3.4 cursor is no longer // optional, but can be set to "empty". // https://docs.mongodb.com/manual/reference/command/aggregate/ "cursor", new BsonDocument() } }); var serverStatus = database.RunCommand <BsonDocument>(new BsonDocument("buildinfo", 1)); if (serverStatus.Contains("version")) { var version = Version.Parse(serverStatus["version"].AsString); if (version < new Version(2, 6)) { throw new InvalidOperationException("Hangfire.Mongo is not able to backup collections in MongoDB running a version prior to 2.6"); } if (version >= new Version(3, 2)) { // The 'bypassDocumentValidation' was introduced in version 3.2 // https://docs.mongodb.com/manual/release-notes/3.2/#rel-notes-document-validation aggregate["bypassDocumentValidation"] = true; } } var dbSource = database.GetCollection <BsonDocument>(collectionName); var indexes = dbSource.Indexes.List().ToList().Where(idx => idx["name"] != "_id_").ToList(); if (indexes.Any()) { var dbBackup = database.GetCollection <BsonDocument>(backupCollectionName); foreach (var index in indexes) { var newIndex = new BsonDocumentIndexKeysDefinition <BsonDocument>(index["key"].AsBsonDocument); var newIndexKeys = index.Names.ToList(); var newOptions = new CreateIndexOptions(); foreach (var key in newIndexKeys) { switch (key) { case "v": newOptions.Version = index[key].AsInt32; break; case "name": newOptions.Name = index[key].AsString; break; case "unique": newOptions.Unique = index[key].AsBoolean; break; case "sparse": newOptions.Sparse = index[key].AsBoolean; break; case "expireAfterSeconds": newOptions.ExpireAfter = TimeSpan.FromSeconds(index[key].AsInt64); break; case "background": newOptions.Background = index[key].AsBoolean; break; case "textIndexVersion": newOptions.TextIndexVersion = index[key].AsInt32; break; case "default_language": newOptions.DefaultLanguage = index[key].AsString; break; case "language_override": newOptions.LanguageOverride = index[key].AsString; break; case "weights": newOptions.Weights = index[key].AsBsonDocument; break; case "min": newOptions.Min = index[key].AsDouble; break; case "max": newOptions.Max = index[key].AsDouble; break; case "bits": newOptions.Bits = index[key].AsInt32; break; case "2dsphereIndexVersion": newOptions.SphereIndexVersion = index[key].AsInt32; break; case "bucketSize": newOptions.BucketSize = index[key].AsDouble; break; } } dbBackup.Indexes.CreateOne(newIndex, newOptions); } } database.RunCommand(new BsonDocumentCommand <BsonDocument>(aggregate)); }
/// <summary> /// Backups the collection in database identified by collectionName. /// </summary> /// <param name="database">Referance to the mongo database.</param> /// <param name="collectionName">The name of the collection to backup.</param> /// <param name="backupCollectionName">Tha name of the backup collection.</param> protected virtual void BackupCollection(IMongoDatabase database, string collectionName, string backupCollectionName) { var aggregate = new BsonDocument(new Dictionary <string, object> { { "aggregate", collectionName }, { "pipeline", new [] { new Dictionary <string, object> { { "$match", new BsonDocument() } }, new Dictionary <string, object> { { "$out", backupCollectionName } } } }, { "allowDiskUse", true }, { // As of MongoDB 3.4 cursor is no longer // optional, but can be set to "empty". // https://docs.mongodb.com/manual/reference/command/aggregate/ "cursor", new BsonDocument() } }); var serverStatus = database.RunCommand <BsonDocument>(new BsonDocument("serverStatus", 1)); if (serverStatus.Contains("version")) { var version = Version.Parse(serverStatus["version"].AsString); if (version < new Version(2, 6)) { throw new InvalidOperationException("Hangfire.Mongo is not able to backup collections in MongoDB running a version prior to 2.6"); } if (version >= new Version(3, 2)) { // The 'bypassDocumentValidation' was introduced in version 3.2 // https://docs.mongodb.com/manual/release-notes/3.2/#rel-notes-document-validation aggregate["bypassDocumentValidation"] = true; } } var dbSource = database.GetCollection <BsonDocument>(collectionName); var indexes = dbSource.Indexes.List().ToList().Where(idx => idx["name"] != "_id_").ToList(); if (indexes.Any()) { var dbBackup = database.GetCollection <BsonDocument>(backupCollectionName); foreach (var index in indexes) { var newIndex = new BsonDocumentIndexKeysDefinition <BsonDocument>(index["key"].AsBsonDocument); var newIndexKeys = index.Names.ToList(); var newOptions = new CreateIndexOptions(); foreach (var mapping in CreateIndexOptionsMapping.Where(m => newIndexKeys.Contains(m.Key))) { var prop = newOptions.GetType().GetTypeInfo().GetProperty(mapping.Name); if (prop != null) { prop.SetValue(newOptions, mapping.Convert(index[mapping.Key].Value)); } } dbBackup.Indexes.CreateOne(newIndex, newOptions); } } database.RunCommand(new BsonDocumentCommand <BsonDocument>(aggregate)); }
async Task <IMongoCollection <BsonDocument> > GetCollection(Type sagaDataType, IEnumerable <ISagaCorrelationProperty> correlationProperties = null) { try { var collectionName = _collectionNameResolver(sagaDataType); var mongoCollection = _mongoDatabase.GetCollection <BsonDocument>(collectionName); var dummy = _verifiedSagaDataTypes.GetOrAdd(sagaDataType, _ => { VerifyBsonSerializerFor(sagaDataType); return(null); }); if (correlationProperties == null) { return(mongoCollection); } async Task CreateIndexes() { if (!_automaticallyCreateIndexes) { return; } _log.Info("Initializing index for saga data {type} in collection {collectionName}", sagaDataType, collectionName); foreach (var correlationProperty in correlationProperties) { // skip this, because there's already an index on 'Id', and it's mapped to '_id' if (correlationProperty.PropertyName == nameof(ISagaData.Id)) { continue; } _log.Debug("Creating index on property {propertyName} of {type}", correlationProperty.PropertyName, sagaDataType); var index = new BsonDocument { { correlationProperty.PropertyName, 1 } }; var indexDef = new BsonDocumentIndexKeysDefinition <BsonDocument>(index); await mongoCollection.Indexes.CreateOneAsync(indexDef, new CreateIndexOptions { Unique = true }); } try { // try to remove any previously created indexes on 'Id' // // we're after this: // {{ "v" : 2, "unique" : true, "key" : { "Id" : 1 }, "name" : "Id_1", "ns" : "rebus2_test__net45.SomeSagaData" }} using (var cursor = await mongoCollection.Indexes.ListAsync()) { while (await cursor.MoveNextAsync()) { var indexes = cursor.Current; foreach (var index in indexes) { var isUnique = index.Contains("unique") && index["unique"].AsBoolean; var hasSingleIdKey = index.Contains("key") && index["key"].AsBsonDocument.Contains("Id") && index["key"].AsBsonDocument.Count() == 1 && index["key"].AsBsonDocument["Id"].AsInt32 == 1; if (isUnique && hasSingleIdKey) { // this is it! var name = index["name"].AsString; await mongoCollection.Indexes.DropOneAsync(name); } } } } } catch { } //<ignore error here, because it is probably a race condition } var initializer = _collectionInitializers.GetOrAdd(sagaDataType, _ => new Lazy <Task>(CreateIndexes)); await initializer.Value; return(mongoCollection); } catch (BsonSchemaValidationException) { throw; } catch (Exception exception) { throw new RebusApplicationException(exception, $"Could not get MongoCollection for saga data of type {sagaDataType}"); } }