c# - 使用 MongoDB C# 驱动程序 (v2.0) 处理收集事件

标签 c# mongodb

使用新的 MongoDB 驱动程序 (v2.0) 非常具有挑战性。您在网上找到的大多数示例仍然引用旧版驱动程序。 The reference manual for v2.0在 Mongo 官方网站上至少可以说是“简洁的”。

我正在尝试做一件简单的事情:检测集合何时发生更改以便将 C# 事件转发到我的服务器应用程序

为此,我找到了以下 C# example (见下文)我正在尝试转换为新的 API。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;

namespace TestTailableCursor {
    public static class Program {
        public static void Main(string[] args) {
            try {
                var server = MongoServer.Create("mongodb://localhost/?safe=true");
                var database = server["test"];

                if (database.CollectionExists("capped")) {
                    database.DropCollection("capped");
                }
                var collectionOptions = CollectionOptions.SetCapped(true).SetMaxDocuments(5).SetMaxSize(10000);
                var commandResult = database.CreateCollection("capped", collectionOptions);
                var collection = database["capped"];

                // to test the tailable cursor manually insert documents into the test.capped collection
                // while this program is running and verify that they are echoed to the console window

                // see: http://www.mongodb.org/display/DOCS/Tailable+Cursors for C++ version of this loop
                BsonValue lastId = BsonMinKey.Value;
                while (true) {
                    var query = Query.GT("_id", lastId);
                    var cursor = collection.Find(query)
                        .SetFlags(QueryFlags.TailableCursor | QueryFlags.AwaitData)
                        .SetSortOrder("$natural");
                    using (var enumerator = (MongoCursorEnumerator<BsonDocument>) cursor.GetEnumerator()) {
                        while (true) {
                            if (enumerator.MoveNext()) {
                                var document = enumerator.Current;
                                lastId = document["_id"];
                                ProcessDocument(document);
                            } else {
                                if (enumerator.IsDead) {
                                    break;
                                }
                                if (!enumerator.IsServerAwaitCapable) {
                                    Thread.Sleep(TimeSpan.FromMilliseconds(100));
                                }
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                Console.WriteLine("Unhandled exception:");
                Console.WriteLine(ex);
            }

            Console.WriteLine("Press Enter to continue");
            Console.ReadLine();
        }

        private static void ProcessDocument(BsonDocument document) 
        {
            Console.WriteLine(document.ToJson());
        }
    }
}

一些(相关)问题:

  1. 对于新驱动程序来说,这是正确的做法吗?
  2. 如果是这样,我该如何设置收集选项(如上例中的 SetCap)。新的 API 包括一个叫做“CollectionSettings”的东西,看起来完全 无关。
  3. 依赖旧版驱动程序是我唯一的选择吗?

感谢您的帮助。

最佳答案

Is my only option to rely on the legacy driver?

没有。

[...] how do I set collection options (like SetCap in the example above). The new API includes something called "CollectionSettings", which seems totally unrelated.

现在有 CreateCollectionSettingsCollectionSettings 是驱动程序的设置,即指定每个集合的默认行为的方法。 CreateCollectionOptions 可以这样使用:

db.CreateCollectionAsync("capped", new CreateCollectionOptions 
      { Capped = true, MaxDocuments = 5, MaxSize = 10000 }).Wait();

Is that the right approach with the new driver?

我认为是的,tailable 游标是数据库的一个特性,避免轮询总是有意义的。

我转换了代码的要点,它似乎可以在我的机器上运行™:

careful when using .Result and .Wait()在 Web 或 UI 应用程序中。

private static void ProcessDocument<T>(T document)where T : class
{
    Console.WriteLine(document.ToJson());
}

static async Task Watch<T>(IMongoCollection<T> collection) where T: class
{ 
    try {
        BsonValue lastId = BsonMinKey.Value;
        while (true) {
            var query = Builders<T>.Filter.Gt("_id", lastId);

            using (var cursor = await collection.FindAsync(query, new FindOptions<T> { 
                CursorType = CursorType.TailableAwait, 
                Sort = Builders<T>.Sort.Ascending("$natural") }))
            {
                while (await cursor.MoveNextAsync())
                {
                    var batch = cursor.Current;
                    foreach (var document in batch)
                    {
                        lastId = document.ToBsonDocument()["_id"];
                        ProcessDocument(document);
                    }
                }
            }
        }
    }
    catch (Exception ex) {
        Console.WriteLine("Unhandled exception:");
        Console.WriteLine(ex);
    }
}

关于c# - 使用 MongoDB C# 驱动程序 (v2.0) 处理收集事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30163586/

相关文章:

c# - 将整数转换为带前导零的二进制字符串

c# - 为其设置模板时,我的 ListView 项目未显示

mongodb - Ubuntu 时区已更改,但 mongodb 仍根据以前的时区打印日期时间

MongoDB - 使用索引查询嵌套字段

javascript - 无法查看 JSON 数据

c# - 停止监听套接字的正确方法

c# - 如何从数据列表创建 json 结构?

c# - 线程安全类是否应该在其构造函数的末尾设置内存屏障?

mongodb - 蒙戈新手: Count of entries where the latest sub-hash has a value within a time range

mongodb - MongoRestore,跳过前n个文档