2015-05-11 38 views
3

使用新的MongoDB驱动程序(v2.0)一直颇具挑战性。您在Web上找到的大多数示例仍然是指传统驱动程序。至少可以说,官方的Mongo网站上的The reference manual for v2.0是“简洁”的。使用MongoDB C#驱动程序处理收集事件(v2.0)

我正在尝试做一件简单的事情:检测集合已更改以便将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. 是我唯一的选择依靠传统的驱动程序?

感谢您的帮助。

回答

3

是我唯一的选择依靠传统的驱动程序?

[...]我怎么设置收集选项(如SetCap在上面的例子)。新的API包括一些名为“CollectionSettings”的东西,这似乎完全不相关。

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

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

是,随着新的驱动程序是正确的做法?

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

我转换的代码的要点,并出现在我的机器 ™上工作:

可通过网络或UI应用程序careful when using .Result and .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); 
    } 
} 
相关问题