使用新的 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());
}
}
}
一些(相关)问题:
- 对于新驱动程序来说,这是正确的做法吗?
- 如果是这样,我该如何设置收集选项(如上例中的 SetCap)。新的 API 包括一个叫做“CollectionSettings”的东西,看起来完全 无关。
- 依赖旧版驱动程序是我唯一的选择吗?
感谢您的帮助。
最佳答案
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.
现在有 CreateCollectionSettings
。 CollectionSettings
是驱动程序的设置,即指定每个集合的默认行为的方法。 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/