i3a*_*non 6 .net c# indexing mongodb mongodb-.net-driver
根据createIndexes命令的文档:
如果您使用一组选项创建索引,然后使用相同的索引字段但不同的选项发出 createIndexes,MongoDB 将不会更改选项也不会重建索引。
解决方案是删除索引并从头开始创建它,但这成本很高。
有没有一种方法可以在没有索引时创建索引,如果有具有相同选项的索引则不执行任何操作,如果选项已更改则替换索引?
这个问题最初是由Phil Barresi 在这里提出的,但后来被删除了。
查看驱动程序,我实现了一种CreateOrUpdateIndex扩展方法,该方法可以比较原始索引文档,如果索引选项已更改,则索引将被替换(只要索引名称保持不变):
public static WriteConcernResult CreateOrUpdateIndex(
this MongoCollection mongoCollection,
IMongoIndexKeys keys,
IMongoIndexOptions options = null)
{
if (mongoCollection.IndexExists(keys))
{
var indexDocument = mongoCollection.GenerateIndexDocument(keys, options);
if (!mongoCollection.GetIndexes().RawDocuments.Any(indexDocument.Equals))
{
mongoCollection.DropIndex(keys);
}
}
return mongoCollection.CreateIndex(keys, options);
}
Run Code Online (Sandbox Code Playgroud)
生成原始索引文档:
public static BsonDocument GenerateIndexDocument(this MongoCollection mongoCollection, IMongoIndexKeys keys, IMongoIndexOptions options)
{
var optionsDocument = options.ToBsonDocument();
var keysDocument = keys.ToBsonDocument();
var indexDocument = new BsonDocument
{
{ "ns", mongoCollection.FullName },
{ "name", GenerateIndexName(keysDocument, optionsDocument) },
{ "key", keysDocument }
};
if (optionsDocument != null)
{
indexDocument.Merge(optionsDocument);
}
return indexDocument;
}
public static string GenerateIndexName(IEnumerable<BsonElement> keys, BsonDocument options)
{
const string name = "name";
if (options != null && options.Contains(name)) return options[name].AsString;
return string.Join("_", keys.Select(element =>
{
var value = "x";
switch (element.Value.BsonType)
{
case BsonType.Int32: value = ((BsonInt32)element.Value).Value.ToString(); break;
case BsonType.Int64: value = ((BsonInt64)element.Value).Value.ToString(); break;
case BsonType.Double: value = ((BsonDouble)element.Value).Value.ToString(); break;
case BsonType.String: value = ((BsonString)element.Value).Value; break;
}
return string.Format("{0}_{1}", element.Name, value.Replace(' ', '_'));
}));
}
Run Code Online (Sandbox Code Playgroud)