简体   繁体   English

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

[英]Handling collection events with MongoDB C# driver (v2.0)

Playing with the new MongoDB driver (v2.0) has been quite challenging. 使用新的MongoDB驱动程序(v2.0)一直非常具有挑战性。 Most of the examples you find on the web still refer to the legacy driver. 您在Web上找到的大多数示例仍然是指旧版驱动程序。 The reference manual for v2.0 on the official Mongo site is "terse", to say the least. 官方Mongo网站上的v2.0参考手册至少可以说是“简洁”。

I'm attempting to do a simple thing: detect when a collection has been changed in order to forward a C# event to my server application . 我正在尝试做一件简单的事情: 检测集合何时被更改以便将C#事件转发到我的服务器应用程序

For doing so, I've found the following C# example (see below) that I'm trying to convert to the new API. 为此,我发现了以下C# 示例 (见下文),我正在尝试转换为新的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());
        }
    }
}

A few (related) questions: 一些(相关)问题:

  1. Is that the right approach with the new driver? 这是新驱动程序的正确方法吗?
  2. If so, how do I set collection options (like SetCap in the example above). 如果是这样,我如何设置集合选项(如上例中的SetCap)。 The new API includes something called "CollectionSettings", which seems totally unrelated. 新的API包含一些名为“CollectionSettings”的东西,它似乎完全不相关。
  3. Is my only option to rely on the legacy driver? 我是唯一依赖传统驱动程序的选择吗?

Thanks for your help. 谢谢你的帮助。

Is my only option to rely on the legacy driver? 我是唯一依赖传统驱动程序的选择吗?

No. 没有。

[...] how do I set collection options (like SetCap in the example above). [...]如何设置集合选项(如上例中的SetCap)。 The new API includes something called "CollectionSettings", which seems totally unrelated. 新的API包含一些名为“CollectionSettings”的东西,它似乎完全不相关。

There's CreateCollectionSettings now. 现在有CreateCollectionSettings CollectionSettings is a setting for the driver, ie a way to specify default behavior per-collection. CollectionSettings是驱动程序的设置,即指定每个集合的默认行为的方法。 CreateCollectionOptions can be used like this: CreateCollectionOptions可以像这样使用:

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

Is that the right approach with the new driver? 这是新驱动程序的正确方法吗?

I think so, tailable cursors are a feature of the database, and avoiding polling always makes sense. 我是这么认为的,tailable游标是数据库的一个特性,避免轮询总是有意义的。

I converted the gist of the code and it appears to work on my machine ™: 我转换了代码的要点,它似乎适用于我的机器 ™:

Be careful when using .Result and .Wait() in a web or UI application. 在Web或UI应用程序中使用.Result.Wait()小心

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM