分组,首先在MongoDb C#驱动程序中抛出NotSupportedException



我正在尝试按name字段对集合进行分组,并使用聚合管道获取具有最大score的文档。

public async Task<IEnumerable<Student>> GetTopAsync(int limit, int offset)
{
var x = await students
.Aggregate(new AggregateOptions{AllowDiskUse = true})
.Group(k => k.Class, g => g.OrderByDescending(o => o.Score).First())
.Skip(offset)
.Limit(limit)
.ToListAsync();
return x;
}

然而,上面的方法抛出了异常:

2020-11-10 10:57:27.3687|1.0.0.0|d3019991-db73-4a98-b331-ac6f00b49331|GlobalExceptionFilter|System.NotSupportedException: Specified method is not supported.
at MongoDB.Driver.Linq.Processors.AccumulatorBinder.GetAccumulatorArgument(Expression node)
at MongoDB.Driver.Linq.Processors.AccumulatorBinder.TryGetAccumulatorTypeAndArgument(PipelineExpression node, AccumulatorType& accumulatorType, Expression& argument)
at MongoDB.Driver.Linq.Processors.AccumulatorBinder.VisitPipeline(PipelineExpression node)
at MongoDB.Driver.Linq.Expressions.PipelineExpression.Accept(ExtensionExpressionVisitor visitor)
at MongoDB.Driver.Linq.Processors.AccumulatorBinder.Bind(Expression node, IBindingContext bindingContext)
at MongoDB.Driver.Linq.Processors.EmbeddedPipeline.EmbeddedPipelineBinder.Bind(Expression node, IBindingContext parent)
at MongoDB.Driver.Linq.Processors.SerializationBinder.BindEmbeddedPipeline(MethodCallExpression node)
at MongoDB.Driver.Linq.Processors.SerializationBinder.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(Expression node)
at MongoDB.Driver.Linq.Processors.SerializationBinder.Bind(Expression node, IBindingContext context, Boolean isClientSideProjection)
at MongoDB.Driver.Linq.Processors.PipelineBindingContext.Bind(Expression node, Boolean isClientSideProjection)
at MongoDB.Driver.Linq.Processors.PipelineBindingContext.Bind(Expression node)
at MongoDB.Driver.Linq.Translators.AggregateGroupTranslator.BindGroup[TKey,TDocument,TResult](PipelineBindingContext bindingContext, Expression`1 groupProjector, IBsonSerializer`1 parameterSerializer, Expression keySelector)
at MongoDB.Driver.Linq.Translators.AggregateGroupTranslator.Translate[TKey,TDocument,TResult](Expression`1 idProjector, Expression`1 groupProjector, IBsonSerializer`1 parameterSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
at MongoDB.Driver.GroupExpressionProjection`3.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.PipelineStageDefinitionBuilder.<>c__DisplayClass19_0`2.<Group>b__0(IBsonSerializer`1 s, IBsonSerializerRegistry sr)
at MongoDB.Driver.DelegatedPipelineStageDefinition`2.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.AppendedStagePipelineDefinition`3.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.AppendedStagePipelineDefinition`3.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.AppendedStagePipelineDefinition`3.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.MongoCollectionImpl`1.AggregateAsync[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
at MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)

我想orderby/first方法没有在驱动程序中实现?实现这一目标的最佳方式是什么?

使用MongoDB.net驱动程序2.17及更高版本,可以在Group()语句中使用First()作为累加器。

在MongoDB.net驱动程序的发行说明中,他们指出:

在$group聚合阶段中支持$topN和相关累加器

发布说明链接:https://mongodb.github.io/mongo-csharp-driver/2.17/what_is_new/

我已经使用First()作为累加器进行了测试,它与更新的驱动程序一起工作。要使用此功能,您需要将MongoDB.net驱动程序更新到2.17.0或更高版本。

对于旧版本,不支持First()作为Group()表达式中的累加器。在使用MongoDB.net驱动程序的2.10版本时,我遇到了问题中提到的同样的异常。更新到最新版本(2.19.1(为我解决了这个问题。