В настоящее время используется MongoDB.Driver v2.11.0 в приложении .Net Core 3.1. Пытался прочитать значения из потока изменений и следил за документацией здесь:
https://mongodb.github.io/mongo-csharp-driver/2.11/reference/driver/change_streams/
Моя проблема в том, что я пытаюсь получить только объекты с определенным типом и обновленным полем, но не могу заставить работать оба фильтра. Я могу заставить измененный поток захватывать только те объекты, которые имеют тип 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, у которых было обновлено поле Status до определенного типа.
Вот что я для этого пробовал:
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' } } ] }";
Но я бы хотел, чтобы он оставался напечатанным, если это возможно.
This fails in the program main with this error
, попробуйте использовать BsonDocument вместо Abc (или любые другие классы). Это позволит избежать проблем с сериализацией, по крайней мере, вначале. - person dododo   schedule 16.09.2020