【问题标题】:MongoDB C# Iteration as enumeratorMongoDB C#迭代作为枚举器
【发布时间】:2016-09-07 14:52:07
【问题描述】:

我有大量的 MongoDB 项目 (> 10m)。

代码在 C#/.NET 中。

有时,我需要遍历所有文档以修剪数据、进行一些其他维护等。 此外,在某些情况下,我需要能够遍历所有文档,但只能获取每个文档的 ID。

我希望文档以 IEnumerable 的形式呈现,供用于处理列表等的代码使用。

我做了以下事情:

    private static IAsyncCursor<MongoAlbum> GetCursor(Parameters...)
    {
        var F = MakeFilter(Parameters...);
        var Cursor = Mongo.Driver.FindAsync(F).Result;
        return Cursor;
    }

    internal static IEnumerable<string> IterateThroughAlbumIds(Parameters...)
    {
        using (var Cursor = GetCursor(Parameters...))
        {
            while (Cursor.MoveNextAsync().Result)
            {
                var Batch = Cursor.Current;
                foreach (var Document in Batch) yield return Document._id;
            }
        }
    }

    internal static IEnumerable<MongoAlbum> IterateThroughAlbums(Parameters...)
    {
        using (var Cursor = GetCursor(Parameters...))
        {
            while (Cursor.MoveNextAsync().Result)
            {
                var Batch = Cursor.Current;
                foreach (var Document in Batch) yield return Document;
            }
        }
    }

现在我想知道两件事:

  • 有没有更好的方法让异步枚举看起来像 .NET IEnumerable?
  • 在枚举过程中,如何告诉驱动只返回一个文档的id?

【问题讨论】:

  • 异步枚举在 .NET 中仍然是一个有问题的概念。当然有 Rx 和 Ix(Entity Framework async 建立在后者的概念之上),但两者都没有统一的支持。更有问题的是 async -> sync 逻辑转换(这就是你在这里得到的)。如果你必须有一个IEnumerable&lt;T&gt;并同步调用它,并且你想用最少的编码工作来做到这一点,那么你正在做的是有点好的(虽然我'd 使用GetAwaiter().GetResult() 进行阻塞而不是Result 用于更清晰的异常传播)。

标签: c# .net mongodb-.net-driver


【解决方案1】:

您为此使用 ToEnumerable 扩展方法并仅获取使用投影所需的 ID。

下面的代码应该可以工作

public class MongoAlbum
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
    public string Property { get; set; }
}
IMongoClient client;
IMongoDatabase database;
IMongoCollection<MongoAlbum> collection;
client = new MongoClient("connection string");
database = client.GetDatabase("DB name");
collection = database.GetCollection<MongoAlbum>("collection name");
IEnumerable<string> albums = collection.Find(x => x.Id == "1")
                                       .Project(x => x.Id)
                                       .ToEnumerable<string>();

在这种情况下,它将是一个字符串列表,因为您只会获得 Ids 结果,并且在我的 MongoAlbum POCO 中我使用了一个字符串。

【讨论】:

    猜你喜欢
    • 2010-11-06
    • 1970-01-01
    • 2012-06-08
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多