问题描述
当前在.Net Core 3.1应用程序中使用MongoDB.Driver v2.11.0。尝试从变更流中读取值,并一直关注此处的文档:
https://mongodb.github.io/mongo-csharp-driver/2.11/reference/driver/change_streams/
我的问题是我试图仅获取具有特定类型和更新字段的对象,但无法使两个过滤器均正常工作。我可以使changestream从完整文档中仅捕获具有Z类型的对象,但无法使任何updateDescription.updatedFields过滤器正常工作。
对象
public class Abc
{
[BsonElement("d")]
public D D{ get; set; }
[BsonElement("e")]
public E E{ get; set; }
}
public class D
{
[BsonElement("type")]
public string Type{ get; set; }
}
public class E
{
[BsonElement("e")]
public F F{ get; set; }
}
public class F
{
[BsonElement("status")]
public string Status { get; set; }
}
因此,在连接到mongo并获取集合之后,这里是用于设置变更流的代码。
protected ChangeStreamOptions _changeStreamOptions => new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
public IChangeStreamCursor<ChangeStreamDocument<Abc>> GetChangeStreamCursor()
{
return _collection.Watch(ConfigurePipeline(),_changeStreamOptions);
}
private PipelineDeFinition<ChangeStreamDocument<Abc>,ChangeStreamDocument<Abc>> ConfigurePipeline()
{
List<IPipelinestageDeFinition> pipeline = new List<IPipelinestageDeFinition>();
pipeline.Add(PipelinestageDeFinitionBuilder.Match(ConfigureFilters()));
return pipeline;
}
private FilterDeFinition<ChangeStreamDocument<Abc>> ConfigureFilters()
{
var builder = Builders<ChangeStreamDocument<Abc>>.Filter;
//here is where I build the filters and having the issues.
//if its just based on the object type It works.
return builder.Eq("fullDocument.d.type","z");
}
这有效,并且只获取具有更新的Z类型的对象没有问题。 如果我尝试添加一个过滤器,则仅返回Z的对象,并且状态字段已更新为特定类型。
这是我为此尝试过的:
builder.Eq("fullDocument.d.type","z") & builder.AnyEq(x => x.UpdateDescription.UpdatedFields.Values,"Action");
builder.Eq("updateDescription.updatedFields.e.f.status","Action");
builder.Eq("e.f.status","Action");
该应用程序将与此一起运行,但永远不会进行任何更改。
由于UpdateDescription.UpdatedFields是一个数组,因此也仅尝试查看更新的字段。
builder.Elemmatch(x => x.UpdateDescription.UpdatedFields,x => x.Name == "e.f.status" && x.Value == "Action")
这在程序主程序中失败并出现此错误
Unable to determine the serialization information for x => x.UpdateDescription.UpdatedFields.'
简而言之,我需要创建一个变更流,并且只获取完整文档中具有特定属性类型且另一个属性已更新为特定类型的对象。
任何帮助将不胜感激!
编辑更新:
如果我将类型更改为BsonDocument,则可以将其作为管道传递,并且可以正常工作:
所以我让它与BsonObject一起使用并使用了它:
var filter = "{ $and: [ { operationType: 'update' }," +
"{ 'fullDocument.d.type' : 'z'}" +
"{ 'updateDescription.updatedFields': { 'e.f.status': 'Action' } } ] }";
但我想尽可能保持输入。
解决方法
所以我想出了一种解决方案,该解决方案适用于我上面描述的方式。
private FilterDefinition<ChangeStreamDocument<Abc>> ConfigureFilters()
{
var builder = Builders<ChangeStreamDocument<Abc>>.Filter;
var filters = builder.And(builder.Eq("fullDocument.d.type","z") & new BsonDocument("e.f.status",new BsonDocument("$eq","Action")));
return filters;
}