【问题标题】:How to set MongoDB Change Stream 'OperationType' in the C# driver?如何在 C# 驱动程序中设置 MongoDB Change Stream 'OperationType'?
【发布时间】:2018-07-18 06:16:26
【问题描述】:

在运行新的 MongDB 服务器 3.6 版并尝试将 Change Stream 监视添加到集合以获取新插入和文档更新的通知时,我只收到更新通知,而不是插入通知。

这是我尝试添加手表的默认方式:

IMongoDatabase mongoDatabase = mongoClient.GetDatabase("Sandbox");
IMongoCollection<BsonDocument> collection = mongoDatabase.GetCollection<BsonDocument>("TestCollection");
var changeStream = collection.Watch().ToEnumerable().GetEnumerator();
changeStream.MoveNext();
var next = changeStream.Current;

然后我从 MongoDB 下载了 C# 源代码,看看他们是如何做到的。查看更改流监视的测试代码,他们创建了一个新文档(插入),然后立即更改该文档(更新),然后设置更改流监视以接收“更新”通知。 没有给出如何查看“插入”通知的示例。

我查看了 MongoDB 网站和 SO 上的 Java 和 NodeJS 示例,这似乎很简单,并且定义了一种查看插入和更新的方法:

var changeStream = collection.watch({ '$match': { $or: [ { 'operationType': 'insert' }, { 'operationType': 'update' } ] } });

C# 驱动程序的 API 大不相同,我原以为他们会为 C# 保留与 Java 和 NodeJS 相同的 API。我发现没有或很少有 C# 做同样事情的例子。

我最接近的是以下尝试,但仍然失败,并且 C# 版本的文档非常有限(或者我没有找到正确的位置)。设置如下:

String json = "{ '$match': { 'operationType': { '$in': ['insert', 'update'] } } }";
var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };

PipelineDefinition<ChangeStreamDocument<BsonDocument>, ChangeStreamDocument<BsonDocument>> pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>().Match(Builders<ChangeStreamDocument<BsonDocument>>.Filter.Text(json,"json"));

然后运行下面的语句会抛出异常:

{"命令聚合失败:$match 与 $text 只允许作为 第一个管道阶段。"}

也没有其他过滤器选项起作用,而且我还没有找到一种方法来输入 JSON 作为字符串来设置“操作类型”。

var changeStream = collection.Watch(pipeline, options).ToEnumerable().GetEnumerator();
changeStream.MoveNext();
var next = changeStream.Current;

我在这里的唯一目标是能够使用 C# 驱动程序设置“操作类型”。有谁知道我做错了什么或者使用 C# 驱动程序尝试过这个并取得了成功?

在阅读了大量的网页后,关于 C# 版本的 MongoDB 驱动程序的信息很少,我非常卡住! 任何帮助将不胜感激。

【问题讨论】:

    标签: c# mongodb mongodb-.net-driver mongodb-csharp-2.0


    【解决方案1】:

    这是我用来更新集合 Watch 以检索“事件”而不只是文档更新的代码示例。

    IMongoDatabase sandboxDB = mongoClient.GetDatabase("Sandbox");
    IMongoCollection<BsonDocument> collection = sandboxDB.GetCollection<BsonDocument>("TestCollection");
    
    //Get the whole document instead of just the changed portion
    ChangeStreamOptions options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
    
    //The operationType can be one of the following: insert, update, replace, delete, invalidate
    var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>().Match("{ operationType: { $in: [ 'replace', 'insert', 'update' ] } }");
    
    var changeStream = collection.Watch(pipeline, options).ToEnumerable().GetEnumerator();
    changeStream.MoveNext();    //Blocks until a document is replaced, inserted or updated in the TestCollection
    ChangeStreamDocument<BsonDocument> next = changeStream.Current;
    enumerator.Dispose();
    

    EmptyPiplineDefinition...Match() 参数也可以是:

    "{ $or: [ {operationType: 'replace' }, { operationType: 'insert' }, { operationType: 'update' } ] }"
    

    如果你想使用 $or 命令,或者

    "{ operationType: /^[^d]/  }"
    

    在那里扔一点正则表达式。最后一个是说,我想要所有的 operationType,除非它们以字母 'd' 开头。

    【讨论】:

    • 太棒了!谢谢,效果很好。不幸的是,这些事情在 MongoDB 中没有完整记录。您的解决方案与我的非工作解决方案接近,我希望将来出现此类问题,更新文档以反映 MongoDB 驱动程序的所有这些功能。感谢您的帮助!
    猜你喜欢
    • 2017-08-13
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    相关资源
    最近更新 更多