c# - 在 Mongo C# 中,分组时,如何创建包含全部内容的组列表?

标签 c# mongodb mongodb-query aggregation-framework

我正在使用 Mongo C# v 2.11.5 按用户的类别 ID 对用户进行分组。我希望变量 list_of_groups 包含一个组列表,其中每个组都有一个组中所有文档的列表,其中每个文档包含其所有单独的属性。我不想在任何字段上应用任何累加器函数。

用户组类是:

public class UserGroup
{
    public string gid {get; set;}
    public List<Users> users { get; set; }
}

我的分组查询是

    var list_of_groups = UserCollection
        .Aggregate()
        .Group(usr => usr.CategoryId,
            g => new UserGroup { gid = g.Key, users = g.ToList() })
        .ToList<UserGroup>();

我想创建一个“列表列表”,其中每个内部列表包含其分组的所有文档,即这种类型的结构:

List<List<UserGroup>>(
- List1<UserGroup> (list of complete documents belonging to CategoryId 1)
- List2<UserGroup> (list of complete documents belonging to CategoryId 2)
- List3<UserGroup> (list of complete documents belonging to CategoryId 3)
)

这不起作用,因为在运行时会生成以下错误:

System.NotSupportedException
  HResult=0x80131515
  Message=Specified method is not supported.
  Source=MongoDB.Driver

谁能指出我在这里遗漏了什么?我一直在兜圈子有一段时间了。我是否应该不使用 Group 函数,也许其他一些函数更合适,因为我不想应用任何累加器函数,并且因为我希望每个组中的每个文档都具有可用的所有属性?

堆栈跟踪:

   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.Expressions.ExtensionExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   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 System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection`1 nodes, Func`2 elementVisitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
   at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   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.MongoCollectionImpl`1.Aggregate[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass19_0`1.<Aggregate>b__0(IClientSessionHandle session)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
   at MongoDB.Driver.CollectionAggregateFluent`2.ToCursor(CancellationToken cancellationToken)

最佳答案

您在这里面临的问题是,.Group() 方法中的所有内容都应转换为相应的 MongoDB/Aggregation Framework 运算符,显然没有 .ToList()对应。因此,如果您想返回文档列表并且必须直接使用 Aggregation Framework 的语法并利用 $$ROOT,那么使用 LINQ 是没有前途的。变量:

public class UserGroup
{
    [BsonElement("_id")]
    public string gid { get; set; }
    public List<User> users { get; set; }
}

var groupDef = new BsonDocument()
{
    { "_id", "$CategoryId" },
    { "users", new BsonDocument(){ { "$push", "$$ROOT" } } }
};

var res = collection.Aggregate().Group<UserGroup>(groupDef).ToList();

关于c# - 在 Mongo C# 中,分组时,如何创建包含全部内容的组列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65596859/

相关文章:

c# - 将持久数据保存在内存中

c# - 对象数组未按预期交付

python - 无法理解 python 多处理

mysql - 我如何在 MongoDB 中重复 MySQL 的 WHERE 1 查询?

mongodb - 如何对 MongoDB 集合中的对象进行分组

json - JSON 对象上的 Mongo 查询

c# - 通过 javascript 调用 C# windows 服务函数

C# - 通过反射获取所有程序集及其类型

mongodb - 如何在MongoDB中使用与聚合不同的方法

mongodb - 更新 Mongodb 中的嵌入文档 : Performance issue?