当前位置: 首页 > 知识库问答 >
问题:

MongoDB-在聚合中选择组,但不指定字段

楮杰
2023-03-14

抱歉发了这么长的帖子!

我有一个Mongo收藏,包含以下文档:

{
    "_id" : ObjectId("592811e3fab9f74b07139d73"),
    "Name" : "John",
    "Value" : 1,
    "AnotherValue": "12345"
},
{
    "_id" : ObjectId("592811f8fab9f74b07139d78"),
    "Name" : "John",
    "Value" : 5,
    "AnotherValue": "55555"
},
{
    "_id" : ObjectId("59281206fab9f74b07139d7e"),
    "Name" : "John",
    "Value" : 12,
    "AnotherValue": "654321"

},
{
    "_id" : ObjectId("59281217fab9f74b07139d81"),
    "Name" : "Chris",
    "Value" : 3,
    "AnotherValue": "11111"
},
{
    "_id" : ObjectId("59281223fab9f74b07139d85"),
    "Name" : "Steve",
    "Value" : 2,
    "AnotherValue": "22222"
},
{
    "_id" : ObjectId("5928122ffab9f74b07139d87"),
    "Name" : "Steve",
    "Value" : 4,
    "AnotherValue": "33333"
}

我想查询这些文档,并返回每个名称的最大值条目,因此我想要的结果集(顺序无关紧要)是:

{
    "_id" : ObjectId("59281206fab9f74b07139d7e"),
    "Name" : "John",
    "Value" : 12,
    "AnotherValue": "654321"
},
{
    "_id" : ObjectId("59281217fab9f74b07139d81"),
    "Name" : "Chris",
    "Value" : 3,
    "AnotherValue": "11111"
},
{
    "_id" : ObjectId("5928122ffab9f74b07139d87"),
    "Name" : "Steve",
    "Value" : 4,
    "AnotherValue": "33333"
}

如果我想在C#中做完全相同的事情,我会使用:

var result = 
    from item in collection
    orderby item.Value descending
    group item by item.Name into itemGroup
    select itemGroup.First();

使用聚合管道,我已经达到了:

db.getCollection('test').aggregate(
[
    { "$sort" : { "Value" : -1 } }, //sort descendingly by the Value field
    { "$group" : { "_id" : "$Name", "highest" : { "$first" : "$$ROOT" }  } }, //group by name and select the first document in the group (as they are sorted descendingly, this will be the document with the highest value)
])

这给了我以下结果集:

{
    "_id" : "Steve",
    "highest" : {
        "_id" : ObjectId("5928122ffab9f74b07139d87"),
        "Name" : "Steve",
        "Value" : 4,
        "AnotherValue": "33333"
    }
},
{
    "_id" : "Chris",
    "highest" : {
        "_id" : ObjectId("59281217fab9f74b07139d81"),
        "Name" : "Chris",
        "Value" : 3,
        "AnotherValue": "11111"
    }
},
{
    "_id" : "John",
   "highest" : {
        "_id" : ObjectId("59281206fab9f74b07139d7e"),
        "Name" : "John",
        "Value" : 12,
        "AnotherValue": "654321"
    }
}

如您所见,我有一个文档数组,每个文档都包含一个“_id”字段(名称)和一个“highest”字段(实际文档)。

这将用C表示为:

var result = 
    from item in collection
    orderby item.Value descending
    group item by item.Name into itemGroup
    select new { id = itemGroup.Key, highest = itemGroup.First() };

我想知道的是,是否可以向我的管道中添加另一个步骤,以确保我只选择实际的person文档,而不是包含person文档的组文档,并且我可以在不指定字段的情况下执行此操作?我希望编写一个C#类,该类能够对各种不同类型的对象使用此查询,因此字段可能未知(假设我可能要使用此查询的每个集合都有名称和值字段,它们都有一些公共属性)。

如果我以完全错误的方式来处理这个问题,那么我会接受全新的建议。只要我最终得到了想要的结果,我就会很高兴。

提前感谢您的帮助。

共有1个答案

卢承弼
2023-03-14

非常感谢尼尔·伦在评论中回答了我的问题。

https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/

MongoDB 3.4有一个$replaceRoot管道选项,可以完全满足我的需要:

db.getCollection('test').aggregate(
[
    { "$sort" : { "Value" : -1 } }, //sort descendingly by the Value field
    { "$group" : { "_id" : "$Name", "highest" : { "$first" : "$$ROOT" }  } }, //group by name and select the first document in the group (as they are sorted descendingly, this will be the document with the highest value)
    { "$replaceRoot": { newRoot: "$highest" } }
])

结果集:

{
    "_id" : ObjectId("5928122ffab9f74b07139d87"),
    "Name" : "Steve",
    "Value" : 4
},
{
    "_id" : ObjectId("59281217fab9f74b07139d81"),
    "Name" : "Chris",
    "Value" : 3
},
{
     "_id" : ObjectId("59281206fab9f74b07139d7e"),
    "Name" : "John",
    "Value" : 12
}
 类似资料:
  • 我很难相信这个问题还没有在某个地方被问到并回答过,但我找不到任何它的痕迹。

  • 我需要筛选此查询,以便不显示值为的文档。当前,我的代码显示以下结果: 我需要一些过滤器,使消失,以便它显示我作为第一个值:。 我以前执行过以下操作:

  • 我在mongodb中的聚合有点问题; 收藏uczelna: 我的合计: 我想找到所有的医生(doktorzy)妇女(名字的最后一个字母a)在一所学校(uczelna)。imie(姓名) 告诉我我做错了什么,谢谢

  • 假设我有一个MongoDB集合,其中包含以下信息: 我想计算按州分组的订单总价的总和,其中项目为“苹果”,颜色为“红色”。我的问题是: 但是,我希望能够将我的结果cust\u id包含在\u id中,它是一个数组/映射/一些结构,其中包含构成我的合计的所有客户id的列表。因此,我希望我的输出包含 是否有办法处理此mongo聚合/查询?或者是一种更好的方式来构造此查询,以便我可以按州分组计算红苹果的

  • 问题内容: 我想查找一位讲师在特定年份教过多少个模块,并想要选择该讲师的姓名和该讲师的模块数。 问题在于,因为我正在选择,并且必须按名称对其进行分组才能使其正常工作。但是,如果有两个讲师姓名相同,该怎么办?然后,sql将使它们合而为一,这将是错误的输出。 因此,我真正想做的是选择,但选择group by ,而sql不允许我这样做。有办法解决吗? 下表是: 到目前为止,这是我的查询: 问题答案:

  • 我正在开发一个Kafka streams应用程序,我遇到了一些麻烦,想知道如何使聚合工作。 我有一个KStream,其中键的类型为,值的类型为,因此我使用 我希望将值聚合在中,其中键将相同,但值将是从我的JSON中提取的。 所以首先我写到: 并且在运行时会出现以下错误: 我知道Kafka在抱怨,因为我试图使用缺省的Json serdes序列化。所以从汇流公司的医生那里我试了一下 但我在编译时遇到了