【问题标题】:MongoDB C# Driver Create IndexMongoDB C# 驱动程序创建索引
【发布时间】:2018-12-17 07:11:52
【问题描述】:

我刚刚将我的 MongoDB 从版本 2.5.0 更新到了 2.7.0。 Visual Studio 告诉我,以下创建索引的方法已过时:

protected override Task OnPerformMaintenanceAsync(CancellationToken cancellationToken) 
    => NotificationLogs.Indexes
                       .CreateOneAsync(Builders<NotificationLog>.IndexKeys
                                                                .Ascending(_ => _.TimestampUtc));

它建议我使用CreateIndexModel

唯一的问题是我找不到一个例子来让这个工作可以做同样的事情。

我试过了:

protected Task OnPerformMaintenanceTestAsync(CancellationToken cancellationToken)
{
  // Old approach
  var builder = Builders<NotificationLog>.IndexKeys
                                         .Ascending(x => x.TimestampUtc);

  // New approach
  var indexModel = new CreateIndexModel<NotificationLog>(nameof(NotificationLog.TimestampUtc));
  
  return NotificationLogs.Indexes.CreateOneAsync(indexModel);
}

但我得到以下异常:

System.FormatException: 'JSON reader was expecting a value but found 'TimestampUtc'.'

【问题讨论】:

  • 附注:“过时”通常是函数作者提供的属性。因此,告诉您这一点的不是 ReSharper,而是 IDE 本身。

标签: c# mongodb-.net-driver


【解决方案1】:

MongoDB 2.7 驱动程序中的新方法是执行以下操作:

var notificationLogBuilder = Builders<NotificationLog>.IndexKeys;
var indexModel = new CreateIndexModel<NotificationLog>(notificationLogBuilder.Ascending(x => x.TimestampUtc));

// .NET Full framwork:
// .NET Standard library:
await IMongoCollection.Indexes
                      .CreateOneAsync(indexModel, cancellationToken: cancellationToken)
                      .ConfigureAwait(false);

// .NET Core:
await IMongoCollection.Indexes
                      .CreateOneAsync(indexModel, cancellationToken: cancellationToken)

【讨论】:

  • 嗨,我试过了,它为我抛出了 Mongodbtimeout 异常。知道是否遗漏了什么吗?
  • 你的max connection idle time 是什么?听起来你需要增加那个时间。这与此查询无关。
  • Mongodb默认连接超时时间为30000ms
【解决方案2】:

对于带有索引选项的 BsonDocument,这里有一个类型不安全的方法:

var indexBuilder = Builders<BsonDocument>.IndexKeys;
var keys = indexBuilder.Ascending("timestamp");
var options = new CreateIndexOptions
{
    Name = "expireAfterSecondsIndex",
    ExpireAfter = TimeSpan.MaxValue
};
var indexModel = new CreateIndexModel<BsonDocument>(keys, options);

// .NET full framework
// .NET Standard library:
await collection.Indexes
                .CreateOneAsync(indexModel, cancellationToken: cancellationToken)
                .ConfigureAwait(false);

// .NET Core
await collection.Indexes
                .CreateOneAsync(indexModel, cancellationToken: cancellationToken);

【讨论】:

  • 你的意思是输入不安全?
【解决方案3】:

以下内容对我有用。

public async Task CreateIndexOnCollection(IMongoCollection<BsonDocument> collection, string field)
{
    var keys = Builders<BsonDocument>.IndexKeys.Ascending(field);
    await collection.Indexes.CreateOneAsync(keys);
}

或者如果我们事先知道我们的索引是什么,我们可以像这样使用强类型实现:

public async Task CreateIndexOnNameField()
{
    var keys = Builders<User>.IndexKeys.Ascending(x => x.Name);
    await _usersCollection.Indexes.CreateOneAsync(keys);
}

【讨论】:

  • 这是过时的方式
  • @StuiterSlurf 真的,你知道如何使用CreateIndexModel吗?
  • @mardok 你是说上面的遮阳篷吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多