MongoDB MongoDB.Driver.GridFS.Delete 上的 createIndexes 异常

MongoDB createIndexes exception on MongoDB.Driver.GridFS.Delete

我正在使用 C# MongoDB.Driver,版本=1.10.1.73

请注意,我知道 this question,不是我的问题。

错误信息:

MongoDB.Driver.MongoWriteConcernException: Command 'createIndexes' failed: exception: Index with name: filename_1_uploadDate_1 already exists with different options (response: { "createdCollectionAutomatically" : false, "numIndexesBefore" : 4, "errmsg" : "exception: Index with name: filename_1_uploadDate_1 already exists with different options", "code" : 85, "ok" : 0.0 })

MongoDatabase _database;
var query = MongoDB.Driver.Builders.Query.And(
    MongoDB.Driver.Builders.Query.EQ(ColumnFilename, filePath),
    MongoDB.Driver.Builders.Query.EQ(ColumnWidth, width),
    MongoDB.Driver.Builders.Query.EQ(ColumnHeight, height));

var mongoFileInfo = _database.GridFS.FindOne(query);
if (mongoFileInfo != null) { 
    var mongoStream = mongoFileInfo.OpenRead();
    if (/*some condition*/) {
        mongoStream.Close();
        mongoStream.Dispose();
        mongoFileInfo.Delete(); // exception here
    }

完整堆栈跟踪:

MongoDB.Driver.MongoCollection.CreateIndex(IMongoIndexKeys keys, IMongoIndexOptions options)
MongoDB.Driver.MongoCollection.CreateIndex(IMongoIndexKeys keys)
MongoDB.Driver.MongoCollection.CreateIndex(String[] keyNames)
MongoDB.Driver.GridFS.MongoGridFS.EnsureIndexes(Int32 maxFiles)
MongoDB.Driver.GridFS.MongoGridFS.EnsureIndexes()
MongoDB.Driver.GridFS.MongoGridFSFileInfo.Delete()

filename_1_uploadDate_1 索引是在我的 Mongo 服务器版本 3.0.7 上默认创建的。 unique 的默认设置是 'not unique'。每当某些代码强制该索引是唯一的(我认为它应该是唯一的)时,上述异常发生在从 Mongo 中删除时。

解决方案:如果索引不存在,则创建它,如果存在且唯一,则重新创建为不唯一。

            CommandResult cr = null;
            IndexOptionsDocument NotUnique = new IndexOptionsDocument("unique", false);
            IndexKeysDocument fileNameUploadDateIdx = new IndexKeysDocument(
                new List<BsonElement> { 
                        new BsonElement(ColumnFilename, 1), 
                        new BsonElement(ColumnUploadDate, 1) });
            var index = indexes.FirstOrDefault(
                i => i.Key.Equals(fileNameUploadDateIdx.ToBsonDocument()));

            if (index == null)
            {
                cr = files.CreateIndex(fileNameUploadDateIdx, NotUnique);
                if (!cr.Ok) {
                    //Cannot create uploadDate index
                }
            }
            else if (index.IsUnique)
            {
                cr = files.DropIndexByName(index.Name);
                if (!cr.Ok) {
                    // Cannot drop index filename_1_uploadDate_1. 
                }
                else
                {
                    cr = files.CreateIndex(fileNameUploadDateIdx, NotUnique);
                    if (!cr.Ok) {
                    //Cannot create uploadDate index
                    }
                }
            }

根据 Mongo docs version 3.2 there's no way to modify options on an index without dropping and creating it all over again. This question tackles this too, and this answer 提供了一种扩展方法来包装此丢弃并从头开始重新创建行为。