public DeviceMongoPublisher(IMongoCollection <DeviceDto> targets, PipelineDefinition <ChangeStreamDocument <DeviceDto>, ChangeStreamDocument <DeviceDto> > pipeline, ChangeStreamOptions options) { cancelToken = tokenSource.Token; action = () => { StartChangeStream(targets); }; t = new Task(action, cancelToken); }
public LocationMongoPublisher(IMongoCollection <LocationDto> collection, PipelineDefinition <ChangeStreamDocument <LocationDto>, ChangeStreamDocument <LocationDto> > pipeline, ChangeStreamOptions options) { cancelToken = tokenSource.Token; action = () => { StartChangeStream(collection); }; t = new Task(action, cancelToken); }
/// <inheritdoc /> public virtual Task <IChangeStreamCursor <TResult> > WatchAsync <TResult>( IClientSessionHandle session, PipelineDefinition <ChangeStreamDocument <BsonDocument>, TResult> pipeline, ChangeStreamOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { return(wrapped.WatchAsync(session, pipeline, options, cancellationToken)); }
public static BaseMongoDbRepository <T> GetSubscribingRepository() { if (CurrentSubscribingRepository == null) { lock (subscriberLockObject) { var currentDocumentType = typeof(T); var currentAssembly = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic) .Single(query => query.FullName == currentDocumentType.Assembly.FullName); foreach (Type exportedType in currentAssembly.GetExportedTypes().Where(query => query.BaseType != null && query.BaseType.UnderlyingSystemType != null && query.BaseType.UnderlyingSystemType.IsGenericType)) { if (exportedType.BaseType.UnderlyingSystemType.GetGenericArguments().FirstOrDefault() == currentDocumentType) { CurrentSubscribingRepository = Activator.CreateInstance(exportedType) as BaseMongoDbRepository <T>; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <T> >().Match("{ operationType: /^[^d]/ }"); ChangeStreamOptions options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var changeStream = CurrentSubscribingRepository.CurrentCollection.Watch(pipeline, options).ToEnumerable().GetEnumerator(); var task = Task.Run(() => { while (true) { try { changeStream.MoveNext(); ChangeStreamDocument <T> next = changeStream.Current; var currentData = next.FullDocument; if (CurrentSubscribingRepository.SubscriptionTriggered == null) { continue; } var receivers = CurrentSubscribingRepository.SubscriptionTriggered.GetInvocationList(); foreach (SubscriptionTriggeredEventHandler receiver in receivers) { receiver.BeginInvoke(CurrentSubscribingRepository, currentData, null, null); } } catch (Exception ex) { } } }); break; } } } } return(CurrentSubscribingRepository); }
/// <summary> /// Listed to the changes in Mongo collection and synch the changes to ElasticSearch index. /// </summary> private void HandleChanges() { log.Info("HandleChanges begin"); try { MongoClient mongoClient = new MongoClient(this.mongoConnectionString); ElasticClient elasticClient = new ElasticClient(new ConnectionSettings(new Uri(this.elasticConnectionString))); IMongoDatabase database = mongoClient.GetDatabase(this.databaseName); IMongoCollection <T> collection = database.GetCollection <T>(this.collectionName); this.cancellationToken.ThrowIfCancellationRequested(); EnsureIndexCreated(elasticClient); //Get the whole document instead of just the changed portion ChangeStreamOptions options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <T> >() .Match("{ operationType: { $in: [ 'insert', 'update', 'delete' ] } }"); using (var stream = collection.Watch(pipeline, options)) { while (!this.cancellationToken.IsCancellationRequested) { try { if (stream.MoveNext()) { var enumerator = stream.Current.GetEnumerator(); while (enumerator.MoveNext()) { HandleChange(elasticClient, enumerator.Current.OperationType, enumerator.Current.FullDocument); } } } catch (Exception ex) { log.Error($"HandleChanges failed.", ex); } Thread.Sleep(ChangeStreamCheckTimeout); this.cancellationToken.ThrowIfCancellationRequested(); } } } catch (Exception ex) { log.Error($"HandleChanges failed.", ex); } }
public IChangeStreamCursor <ChangeStreamDocument <TModel> > Watch() { var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <TModel> >().Match("{ operationType: { $in: [ 'insert', 'delete' ] } }"); return(_mongoCollection.Watch <ChangeStreamDocument <TModel> >(pipeline, options)); }
public UnifiedCreateChangeStreamOnDatabaseOperation( IMongoDatabase database, BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline, ChangeStreamOptions options) { _database = database; _pipeline = pipeline; _options = options; }
public UnifiedCreateChangeStreamOnClientOperation( IMongoClient client, BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline, ChangeStreamOptions options) { _client = client; _pipeline = pipeline; _options = options; }
public UnifiedCreateChangeStreamOnCollectionOperation( IMongoCollection <BsonDocument> collection, BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline, ChangeStreamOptions options) { _collection = collection; _pipeline = pipeline; _options = options; }
/// <summary> /// Fügt eine Organisation in die Datenbank hinzu /// </summary> /// <param name="entry"></param> //internal void AddOrganization(Organization entry) //{ // entry.Verify(); // organisations.InsertOne(entry); //} /// <summary> /// Listener Für Änderungen in der Entry Datenbank /// Sorgt mit hilfe von SignalR dafür, das die Frontends aktualsiert werden. /// Prüft ob es eine Organisation gibt, welche eine benachrichtigung z.b. über email aboniert hat und versendert die. /// Es ist auch möglich sich auf die PLZ 00000 zu Registrieren. /// </summary> private async void Listen() { var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <Entry> >() .Match("{ operationType: { $in: [ 'insert','replace', 'update' ] }}") .Project("{ fullDocument: 1 }"); using var cursor = requests.Watch(pipeline, options); await cursor.ForEachAsync(change => { Entry entry = BsonSerializer.Deserialize <Entry>((BsonDocument)change.Elements.ToList()[1].Value); if (entry.zip.Equals("00000")) { var send = entry.TrasportModel; _hubContext.Clients.All.SendAsync("ItemChange", send); //foreach (Organization organisation in organisations.Find("{ \"zips\": {$in: [ '00000', ]}}").ToList<Organization>()) //{ // var notifikation = new Notifikation() // { // entry = entry.id.ToString(), // organisation = organisation.id.ToString(), // timestamp = DateTime.Now // }; // if (TryAddNotifkation(notifikation)) // { // notifikationFactory.Send(notifikation, organisation, entry); // } //} } //else //{ // StringBuilder sb = new StringBuilder(); // for (int i = 0; i < entry.zip.Length; i++) // { // sb.Append('\''); // sb.Append(entry.zip.Substring(0, entry.zip.Length - i)); // sb.Append("', "); // } // foreach (Organization organisation in organisations.Find($"{{ \"zips\": {{$in: [ {sb.ToString()} ]}}}}").ToList<Organization>()) // { // var notifikation = new Notifikation() // { // entry = entry.id.ToString(), // organisation = organisation.id.ToString(), // timestamp = DateTime.Now // }; // if (TryAddNotifkation(notifikation)) // { // notifikationFactory.Send(notifikation, organisation, entry); // } // } //} }); }
private ChangeStreamOptions ParseChangeStreamOptions(BsonDocument document) { var options = new ChangeStreamOptions(); foreach (var element in document) { throw new FormatException($"Invalid change stream option: \"{element.Name}\"."); } return(options); }
private static async Task TriggerChangeStreamAsync() { Console.WriteLine("TriggerChangeStream Method start"); try { MongoClient dbClient = new MongoClient("mongodb://*****:*****@deliverymoment-cosmos-mongo-db.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&maxIdleTimeMS=120000&appName=@deliverymoment-cosmos-mongo-db@"); //Database List //Get Database and Collection Console.WriteLine("Get Database : deliverymoment-db :"); IMongoDatabase db = dbClient.GetDatabase("deliverymoment-db"); Console.WriteLine("Get Deilverymoment Collection :"); var deliveryColl = db.GetCollection <BsonDocument>("delivery-moment"); Console.WriteLine("Changestream code start"); //change feed code start var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <BsonDocument> >() .Match(change => change.OperationType == ChangeStreamOperationType.Insert || change.OperationType == ChangeStreamOperationType.Update || change.OperationType == ChangeStreamOperationType.Replace) .AppendStage <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument>, BsonDocument>( "{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}"); var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var enumerator = deliveryColl.Watch(pipeline, options).ToEnumerable().GetEnumerator(); Console.WriteLine("Reading Change stream while loop start"); while (enumerator.MoveNext()) { //publish message to Confluent Kafka var document = enumerator.Current; Console.WriteLine($"Start publishing messaage : {document}"); await DeliveryMomentMessageHandler.PublishMessage(document.ToString()); Console.WriteLine($"End publishing messaage : {document}"); } enumerator.Dispose(); Console.WriteLine("Reading Change stream while loop end"); //change feed code end } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } Console.WriteLine("TriggerChangeStream Method end"); }
public async Task <IChangeStreamCursor <ChangeStreamDocument <Notification> > > GetNotificationChangeStreamCursorAsync() { var mongoClient = new MongoClient(_server); IMongoDatabase database = mongoClient.GetDatabase(_database); var collection = database.GetCollection <Notification>(_collection); var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <Notification> >().Match("{ operationType: { $in: [ 'insert' ] } }"); IChangeStreamCursor <ChangeStreamDocument <Notification> > cursor = await collection.WatchAsync(pipeline, options); return(cursor); }
private async Task QueryCurrentAsync(string?streamFilter, StreamPosition lastPosition) { BsonDocument?resumeToken = null; var start = lastPosition.Timestamp.Timestamp > 0 ? lastPosition.Timestamp.Timestamp - 30 : SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromSeconds(30)).ToUnixTimeSeconds(); var changePipeline = Match(streamFilter); var changeStart = new BsonTimestamp((int)start, 0); while (!stopToken.IsCancellationRequested) { var changeOptions = new ChangeStreamOptions(); if (resumeToken != null) { changeOptions.StartAfter = resumeToken; } else { changeOptions.StartAtOperationTime = changeStart; } using (var cursor = eventStore.TypedCollection.Watch(changePipeline, changeOptions, stopToken.Token)) { var isRead = false; await cursor.ForEachAsync(async change => { if (change.OperationType == ChangeStreamOperationType.Insert) { foreach (var storedEvent in change.FullDocument.Filtered(lastPosition)) { await eventSubscriber.OnEventAsync(this, storedEvent); } } isRead = true; }, stopToken.Token); resumeToken = cursor.GetResumeToken(); if (!isRead) { await Task.Delay(1000); } } } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <User> >() .Match(x => x.OperationType == ChangeStreamOperationType.Replace || x.OperationType == ChangeStreamOperationType.Update); using var cursor = _users.Watch(pipeline, options, stoppingToken); await cursor.ForEachAsync(async document => { await _userHubContext.SendUpdateAsync(document.FullDocument); }, stoppingToken); }
public void Test3() { var mockClient = new Mock <IMongoClient>(); var mockContext = new Mock <IMongoContext>(); var client = mockClient.Object; var mockCollection = CreateMockCollection(); var collection = mockCollection.Object; var session = new Mock <IClientSessionHandle>().Object; var options = new ChangeStreamOptions(); var cancellationToken = new CancellationTokenSource().Token; Book document = new Book(); document.Author = "asdas"; document.BookName = "sadasd"; document.Id = ObjectId.GenerateNewId().ToString(); collection.InsertOne(document); mockContext.Setup(x => x.GetCollection <Book>("Book")).Returns(collection); BookstoreDatabaseSettings setting = new BookstoreDatabaseSettings(); setting.BooksCollectionName = "Book"; var mockIDBsettings = new Mock <IOptions <BookstoreDatabaseSettings> >(); mockIDBsettings.Setup(x => x.Value).Returns(setting); BookService service = new BookService(mockIDBsettings.Object, mockContext.Object); var result = service.Create(document); mockContext.Verify(x => x.GetCollection <Book>("Book"), Times.Once); var filterDefinition = Builders <Book> .Filter.Eq("BookName", "sadasd"); var options1 = new FindOptions <Book>(); // no projection var filterExpression = (Expression <Func <Book, bool> >)(x => x.BookName == "sadasd"); //FindFluent<Book, Book> fluent; //mockCollection.Verify(x=>x.Find(filterExpression, null), Times.Once); mockCollection.Verify(m => m.FindAsync <Book>(It.IsAny <ExpressionFilterDefinition <Book> >(), options1, cancellationToken), Times.Once); }
private static ChangeStreamOptions BuildChangeStreamOptions(BsonDocument resumeToken) { var changeStreamOptions = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption .UpdateLookup // Confgure to get full document whilst getting the update operation [by default update does not include full document] }; if (!resumeToken.GetElement("_data").Value.IsBsonNull) { changeStreamOptions.ResumeAfter = resumeToken; // Confugre the resume token here, if any } return(changeStreamOptions); }
public void ChangeStreamExample3() { var client = DriverTestConfiguration.Client; var database = client.GetDatabase("ChangeStreamExamples"); database.DropCollection("inventory"); var inventory = database.GetCollection <BsonDocument>("inventory"); var documents = new[] { new BsonDocument("x", 1), new BsonDocument("x", 2) }; IChangeStreamCursor <ChangeStreamDocument <BsonDocument> > previousCursor; { new Thread(() => { Thread.Sleep(TimeSpan.FromMilliseconds(100)); inventory.InsertMany(documents); }) .Start(); previousCursor = inventory.Watch(new ChangeStreamOptions { BatchSize = 1 }); while (previousCursor.MoveNext() && previousCursor.Current.Count() == 0) { } // keep calling MoveNext until we've read the first batch } { // Start Changestream Example 3 var resumeToken = previousCursor.GetResumeToken(); var options = new ChangeStreamOptions { ResumeAfter = resumeToken }; var cursor = inventory.Watch(options); cursor.MoveNext(); var next = cursor.Current.First(); cursor.Dispose(); // End Changestream Example 3 next.FullDocument.Should().Be(documents[1]); } }
public async void ListenAsync() { var option = new ChangeStreamOptions { StartAtOperationTime = new BsonTimestamp((int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds, 0) }; using (var cursor = await Collection.WatchAsync(option)) { while (await cursor.MoveNextAsync()) { foreach (var csd in cursor.Current) { Cache.Replace(csd.FullDocument); } } } }
private ChangeStreamOptions ParseChangeStreamOptions(BsonDocument document) { var options = new ChangeStreamOptions(); foreach (var element in document) { switch (element.Name) { case "batchSize": options.BatchSize = element.Value.ToInt32(); break; default: throw new FormatException($"Invalid change stream option: \"{element.Name}\"."); } } return(options); }
public IEnumerator <ChangeStreamDocument <TEntity> > SubscribeToChangesStreamMany( PipelineDefinition <ChangeStreamDocument <TEntity>, ChangeStreamDocument <TEntity> > pipeline ) { if (pipeline == null) { return(null); } var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var cursor = _mongoCollection.Watch(pipeline, options); var enumerator = cursor.ToEnumerable().GetEnumerator(); return(enumerator); }
public UnifiedCreateChangeStreamOnCollectionOperation Build(string targetCollectionId, BsonDocument arguments) { var collection = _entityMap.GetCollection(targetCollectionId); ChangeStreamOptions options = null; BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline = null; foreach (var argument in arguments) { switch (argument.Name) { case "batchSize": options ??= new ChangeStreamOptions(); options.BatchSize = argument.Value.AsInt32; break; case "comment": options ??= new ChangeStreamOptions(); options.Comment = argument.Value; break; case "fullDocument": options ??= new ChangeStreamOptions(); options.FullDocument = (ChangeStreamFullDocumentOption)Enum.Parse(typeof(ChangeStreamFullDocumentOption), argument.Value.AsString, true); break; case "fullDocumentBeforeChange": options ??= new ChangeStreamOptions(); options.FullDocumentBeforeChange = (ChangeStreamFullDocumentBeforeChangeOption)Enum.Parse(typeof(ChangeStreamFullDocumentBeforeChangeOption), argument.Value.AsString, true); break; case "pipeline": var stages = argument.Value.AsBsonArray.Cast <BsonDocument>(); pipeline = new BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> >(stages); break; default: throw new FormatException($"Invalid CreateChangeStreamOperation argument name: '{argument.Name}'."); } } return(new UnifiedCreateChangeStreamOnCollectionOperation(collection, pipeline, options)); }
public void ChangeStreamExample3() { var client = DriverTestConfiguration.Client; var database = client.GetDatabase("ChangeStreamExamples"); database.DropCollection("inventory"); var inventory = database.GetCollection <BsonDocument>("inventory"); var documents = new[] { new BsonDocument("x", 1), new BsonDocument("x", 2) }; ChangeStreamDocument <BsonDocument> lastChangeStreamDocument; { new Thread(() => { Thread.Sleep(TimeSpan.FromMilliseconds(100)); inventory.InsertMany(documents); }) .Start(); var enumerator = inventory.Watch().ToEnumerable().GetEnumerator(); enumerator.MoveNext(); lastChangeStreamDocument = enumerator.Current; } { // Start Changestream Example 3 var resumeToken = lastChangeStreamDocument.ResumeToken; var options = new ChangeStreamOptions { ResumeAfter = resumeToken }; var enumerator = inventory.Watch(options).ToEnumerable().GetEnumerator(); enumerator.MoveNext(); var next = enumerator.Current; enumerator.Dispose(); // End Changestream Example 3 next.FullDocument.Should().Be(documents[1]); } }
public void CreateChangeStreamOperation_for_collection_returns_expected_result() { var databaseNamespace = new DatabaseNamespace("databaseName"); var collectionNamespace = new CollectionNamespace(databaseNamespace, "collectionName"); var mockCollection = new Mock <IMongoCollection <BsonDocument> >(); mockCollection.SetupGet(m => m.CollectionNamespace).Returns(collectionNamespace); var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <BsonDocument> >().Limit(1); var documentSerializer = BsonDocumentSerializer.Instance; var options = new ChangeStreamOptions { BatchSize = 123, Collation = new Collation("en-us"), FullDocument = ChangeStreamFullDocumentOption.UpdateLookup, FullDocumentBeforeChange = ChangeStreamFullDocumentBeforeChangeOption.Off, MaxAwaitTime = TimeSpan.FromSeconds(123), ResumeAfter = new BsonDocument(), StartAfter = new BsonDocument(), StartAtOperationTime = new BsonTimestamp(1, 2) }; var readConcern = new ReadConcern(); var messageEncoderSettings = new MessageEncoderSettings(); var renderedPipeline = RenderPipeline(pipeline); var result = ChangeStreamHelper.CreateChangeStreamOperation(mockCollection.Object, pipeline, documentSerializer, options, readConcern, messageEncoderSettings, true); result.BatchSize.Should().Be(options.BatchSize); result.Collation.Should().BeSameAs(options.Collation); result.CollectionNamespace.Should().BeSameAs(collectionNamespace); result.DatabaseNamespace.Should().BeNull(); result.FullDocument.Should().Be(options.FullDocument); result.FullDocumentBeforeChange.Should().Be(options.FullDocumentBeforeChange); result.MaxAwaitTime.Should().Be(options.MaxAwaitTime); result.MessageEncoderSettings.Should().BeSameAs(messageEncoderSettings); result.Pipeline.Should().Equal(renderedPipeline.Documents); result.ReadConcern.Should().BeSameAs(readConcern); result.ResultSerializer.Should().BeOfType <ChangeStreamDocumentSerializer <BsonDocument> >(); result.ResumeAfter.Should().BeSameAs(options.ResumeAfter); result.RetryRequested.Should().Be(true); result.StartAfter.Should().BeSameAs(options.StartAfter); result.StartAtOperationTime.Should().BeSameAs(options.StartAtOperationTime); }
public static IObservable <ChangeStreamDocument <T> > WhenCollectionChanges <T>(this IMongoCollection <T> collection, CancellationToken cancellationToken = default, params ChangeStreamOperationType[] operationTypes) { if (operationTypes.Length == 0) { operationTypes = new[] { ChangeStreamOperationType.Insert, ChangeStreamOperationType.Update, ChangeStreamOperationType.Replace, ChangeStreamOperationType.Delete }; } // { operationType: { $in: [...] } } var filter = new FilterDefinitionBuilder <ChangeStreamDocument <T> >() .In(d => d.OperationType, operationTypes); var pipelineDefinition = new EmptyPipelineDefinition <ChangeStreamDocument <T> >() .Match(filter); var options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var changeStreamCursor = collection.Watch(pipelineDefinition, options, cancellationToken); return(Observable.Create <ChangeStreamDocument <T> >(observer => { Task.Run(async() => { while (true) { if (await changeStreamCursor.MoveNextAsync(cancellationToken)) { foreach (var c in changeStreamCursor.Current) { observer.OnNext(c); cancellationToken.ThrowIfCancellationRequested(); } } cancellationToken.ThrowIfCancellationRequested(); } }, cancellationToken); return Disposable.Create(() => changeStreamCursor.Dispose()); })); }
public async Task SubscribeById(string docId) { // Much of the streaming options, query is taken from here. // https://stackoverflow.com/questions/48672584/how-to-set-mongodb-change-stream-operationtype-in-the-c-sharp-driver // Set options. // Get the whole document instead of just the changed portion var options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; // Set our matching criteria // Example: The operationType can be one of the following: insert, update, replace, delete, invalidate // Example: var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>().Match("{ operationType: { $in: [ 'replace', 'insert', 'update' ] } }"); var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <TargetDto> >() .Match(t => t.FullDocument.Id == Guid.Parse("")); Guid subscriptionId = _targetDbService.Subscribe(pipeline, options); }
public override void Watch(Action <EventRecord> callback) { var options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <EventRecord> >().Match("{ operationType: { $in: [ 'insert' ] } }"); var changesCursor = Collection .Watch(pipeline, options) .ToEnumerable() .GetEnumerator(); while (changesCursor.MoveNext()) { var record = changesCursor.Current.FullDocument; InvokeCallback(callback, record); } }
public async IAsyncEnumerable <Envelope> Watch( Checkpoint?checkpoint, CancellationToken cancellation ) { while (!await EventsCollectionExists()) { _logger.LogDebug("Waiting for events collection to appear..."); await Task.Delay(100, cancellation); } var envelopes = Load(checkpoint, cancellation); checkpoint ??= new Checkpoint(); await foreach (var envelope in envelopes) { checkpoint.Value = envelope.MessageId; yield return(envelope); } var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup, }; var from = CheckpointToFilter(d => d["FullDocument"]["_id"], checkpoint); var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <Envelope> >() .Match(x => x.OperationType == ChangeStreamOperationType.Insert) .Match(x => from.Inject()); using var cursor = await _events.WatchAsync(pipeline, options, cancellation); while (await cursor.MoveNextAsync(cancellation)) { foreach (var change in cursor.Current) { yield return(change.FullDocument); } } }
public static void hookMessage(User sender, User reciever) { var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var change = getObjectCollection().Watch(options).ToEnumerable().GetEnumerator(); while (change.MoveNext()) { var query = Builders <Message> .Filter.Eq("Sender", sender.Username) & Builders <Message> .Filter.Eq("Reciever", reciever.Username) & Builders <Message> .Filter.Eq("Status", "0"); var list = getObjectCollection().Find(query).ToList(); foreach (Message DocMsg in list) { Console.WriteLine(DocMsg.Sender + " to " + DocMsg.Reciever + " : " + DocMsg.MessageText); msgstack.Enqueue(DocMsg); UpdateReadStatus(DocMsg); } } }
public void ChangeStreamExample2() { var client = DriverTestConfiguration.Client; var database = client.GetDatabase("ChangeStreamExamples"); database.DropCollection("inventory"); var inventory = database.GetCollection <BsonDocument>("inventory"); var document = new BsonDocument("x", 1); inventory.InsertOne(document); new Thread(() => { Thread.Sleep(TimeSpan.FromMilliseconds(100)); var filter = new BsonDocument("_id", document["_id"]); var update = "{ $set : { x : 2 } }"; inventory.UpdateOne(filter, update); }) .Start(); // Start Changestream Example 2 var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; var cursor = inventory.Watch(options); while (cursor.MoveNext() && cursor.Current.Count() == 0) { } // keep calling MoveNext until we've read the first batch var next = cursor.Current.First(); cursor.Dispose(); // End Changestream Example 2 var expectedFullDocument = document.Set("x", 2); next.FullDocument.Should().Be(expectedFullDocument); }