2015-05-11 4 views
3

Игра с новым драйвером MongoDB (v2.0) была довольно сложной задачей. Большинство примеров, которые вы найдете в Интернете, по-прежнему относятся к устаревшему драйверу. 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

Является ли это единственным вариантом, чтобы полагаться на старый драйвер?

No.

[...] Как настроить параметры сбора (например, SetCap в примере выше). Новый API включает в себя что-то, называемое «CollectionSettings», которое кажется совершенно несвязанным.

Сейчас CreateCollectionSettings. CollectionSettings - это параметр для драйвера, то есть способ указания поведения по умолчанию для каждой коллекции. CreateCollectionOptions может быть использован, как это:

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

Это правильный подход с новым драйвером?

Я думаю, что так называемые хвостовые курсоры являются особенностью базы данных, и избежать опроса всегда имеет смысл.

я преобразовал суть кода и , кажется, работает на моей машине ™:

Будьте в веб или пользовательского интерфейса приложения 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); 
    } 
} 
Смежные вопросы