繁体   English   中英

如何使用BsonClassMap更改MongoDB C#Driver类反序列化的方式?

[英]How can I use BsonClassMap to change the way a MongoDB C# Driver class is deserialized?

由于我将过滤器应用于变更流(在SO上讨论: 如何从MongoDB中的ChangeStream 过滤对特定字段的更新 ),我得到的是BsonDocument而不是ChangeStreamDocument对象。 此BsonDocument与ChangeStreamDocument的唯一不同之处在于,它包含一个额外的元素,称为“ tmpfields”。

在我的场景中,我仍然需要文档中的ResumeToken和其他元素,因此我想将此BsonDocument转换为ChangeStreamDocument对象。 我的第一次尝试是使用BsonSerializer.Deserialize<ChangeStreamDocument<BsonDocument>>( doc) ,其中doc是我返回的BsonDocument。 但是,由于它具有额外的tmpfields元素,因此不允许这样做。

我尝试注册BsonClassMap,因为ChangeStreamDocument类是C#驱动程序的一部分,并且无法将[BsonIgnoreExtraElements]属性添加到该类中,但是我没有成功:

BsonClassMap.RegisterClassMap<ChangeStreamDocument<BsonDocument>>(cm =>
{
    cm.AutoMap();
    cm.SetIgnoreExtraElements(true);
});

AutoMap()不能正常工作,但是我遇到了一个“找不到匹配的创建者”的例外。 我尝试了cm.MapCreator(...) ,但是那里也没有成功。 我将AutoMap()调出(只离开了SetIgnoreExtraElements行),并收到有关无法匹配属性(_id等)的错误。 因此,我为每个属性尝试了诸如cm.MapProperty(c => c.DocumentKey).SetElementName("documentKey")之类的行,但是当我使用Deserialize()方法时,它们从未设置过-它们留为null。

现在,我已恢复使用doc["field"].AsXYZ方法从BsonDocument获取所需的值,但是我想学习一种更好的方法。

使用RegisterClassMap是否正确? 如果是这样,我想念什么?

我无法将[BsonIgnoreExtraElements]属性添加到该类

如果您只是想忽略多余的字段。 您可以添加一个额外的聚合管道$project来删除该字段。

例如

var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
var addFields = new BsonDocument { { "$addFields", new BsonDocument { { "tmpfields", new BsonDocument { { "$objectToArray", "$updateDescription.updatedFields" } } } } } };
var match = new BsonDocument { { "$match", new BsonDocument { { "tmpfields.k", new BsonDocument { { "$nin", new BsonArray{"a", "b"} } } } } } };

// Remove the unwanted field. 
var project = new BsonDocument { {"$project", new BsonDocument { {"tmpfields", 0 } } } };
var pipeline = new[] { addFields, match, project };

var cursor = collection.Watch<ChangeStreamDocument<BsonDocument>>(pipeline, options);

var enumerator = cursor.ToEnumerable().GetEnumerator();
while(enumerator.MoveNext())
{
     ChangeStreamDocument<BsonDocument> doc = enumerator.Current;
     Console.WriteLine(doc.DocumentKey); 

 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM