MongoDB ChangeStream 过滤/匹配

问题描述 投票:0回答:1

我试图实现以下过滤器目标:

UpdateDescription.UpdateFields
中任何一个字段的存在以及操作类型

为了实现目标,我尝试使用

PipelineDefinition.Match
扩展函数的表达式类型参数重载,如下所示:

var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>()
    .Match(
(ChangeStreamDocument<BsonDocument> doc) =>
     doc.UpdateDescription.UpdatedFields.Any(c => fieldNameList.Contains(c.Name))
     &&
     doc.OperationType == _operationType);

但我最终收到以下错误:

System.NotSupportedException: 'Serializer for MongoDB.Driver.ChangeStreamUpdateDescription must implement IBsonDocumentSerializer to be used with LINQ.'

我尝试向

ChangeStreamDocumentSerializer
提供一个新的
EmptyPipelineDefinition
实例以及匹配过滤器,但也出现了相同的错误。

如何在 LINQ 过滤器中使用

UpdateDescription

mongodb mongodb-.net-driver
1个回答
0
投票

我最终构建了 FilterDefinition 和 FieldDefinition 来解决所描述的问题:

builder.Ne($"updateDescription.updatedFields.{memberExpression.Member.Name}", BsonNull.Value)

我使用循环构建最终解决方案,如下所示:

            var dynamicFilter = builder.Empty;
            var fieldFilter = new List<FilterDefinition<ChangeStreamDocument<BsonDocument>>>();
            var operationFilter = new List<FilterDefinition<ChangeStreamDocument<BsonDocument>>>();

            foreach (var field in _fields)
            {
                var memberExpression = (MemberExpression)field.Body;

                fieldFilter.Add(builder
                    .Ne($"updateDescription.updatedFields.{memberExpression.Member.Name}", BsonNull.Value));
            }

            foreach (var operationType in _operationTypes)
            {
                operationFilter.Add(builder.Eq(c => c.OperationType, operationType));
            }

            dynamicFilter = builder.And(builder.Or(fieldFilter), builder.Or(operationFilter));

为了编译时安全,我更愿意使用类型化变体而不是过滤器定义字符串,但我遇到了本文中报告的原始问题的另一种表现形式。我相信那些基于字符串的字段定义是区分大小写的。因此,使用此解决方案时请务必小心。

© www.soinside.com 2019 - 2024. All rights reserved.