【问题标题】:Field must be an accumulator object error when trying to group by object as key尝试按对象分组作为键时,字段必须是累加器对象错误
【发布时间】:2019-09-20 21:17:43
【问题描述】:

我正在尝试按集合中的多个属性对文档进行类型安全分组。我发现问题不在于多个属性本身的分组,而是关键是一个对象(new { })而不是字符串。

这行得通:

collection.Aggregate().Group(x => x.Name, x => new { Name = x.Key, Count = x.Sum(s => 1) }).ToList();

这不起作用:

collection.Aggregate().Group(x => new { Name = x.Name }, x => new { Name = x.Key.Name, Count = x.Sum(s => 1) }).ToList();

错误是:

MongoDB.Driver.MongoCommandException:'命令聚合失败:字段'名称'必须是累加器对象。'

当我将不起作用的查询转换为字符串时,我得到以下信息:

aggregate([{ "$group" : { "_id" : { "Name" : "$Name" }, "Name" : "$_id.Name", "Count" : { "$sum" : 1 } } }])

我想这里的问题是这部分"Name" : "$_id.Name"。我该如何解决这个问题?

我目前正在使用 2.8.0 版本的 mongodb 驱动程序。

【问题讨论】:

    标签: c# mongodb .net-core aggregation-framework mongodb-.net-driver


    【解决方案1】:

    实际上,驱动程序在这里运行正常,但您遇到的是聚合框架中$group 管道阶段的限制。该文档指出:

    输出文档包含一个 _id 字段,其中包含按键的不同组。输出文档还可以包含计算字段,这些字段包含由 $group 的 _id 字段分组的某些 accumulator 表达式的值

    因此,在您的情况下,您尝试在没有任何累加器的情况下引用 _id 字段。

    从逻辑角度来看,您的查询看起来很相似。第一个被翻译成:

    {
        "$group" : {
            "_id" : "$Name",
            "Count" : {
                "$sum" : 1
            }
        }
    }
    

    第二个将返回相同的数据,但您有一个对象作为分组键。要在 C# 中解决这个问题,您需要引入 .First() 表达式,该表达式将被转换为 $first,因此运行:

    Col.Aggregate()
        .Group(
            x => new { Name = x.Name }, 
            x => new { Name = x.First().Name, Count = x.Sum(s => 1) })
        .ToList();
    

    将在数据库上运行以下查询:

    {
        "$group" : {
            "_id" : {
                "Name" : "$Name"
            },
            "Name" : {
                "$first" : "$Name"
            },
            "Count" : {
                "$sum" : 1
            }
        }
    }
    

    它可以工作,但逻辑上它返回与第一次聚合相同的数据

    【讨论】:

      猜你喜欢
      • 2017-10-17
      • 2020-01-01
      • 2019-06-23
      • 1970-01-01
      • 2019-07-16
      • 2018-01-01
      • 2017-01-17
      • 1970-01-01
      • 2017-11-20
      相关资源
      最近更新 更多