Mongodb 在Mongo聚合管道上使用$last

Mongodb 在Mongo聚合管道上使用$last,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我搜索了类似的问题,但没有找到。请随意为我指出他们的方向 假设我有这些数据: { "_id" : ObjectId("5694c9eed4c65e923780f28e"), "name" : "foo1", "attr" : "foo" } { "_id" : ObjectId("5694ca3ad4c65e923780f290"), "name" : "foo2", "attr" : "foo" } { "_id" : ObjectId("5694ca47d4c65e923780f294"),

我搜索了类似的问题,但没有找到。请随意为我指出他们的方向

假设我有这些数据:

{ "_id" : ObjectId("5694c9eed4c65e923780f28e"), "name" : "foo1", "attr" : "foo" }
{ "_id" : ObjectId("5694ca3ad4c65e923780f290"), "name" : "foo2", "attr" : "foo" }
{ "_id" : ObjectId("5694ca47d4c65e923780f294"), "name" : "bar1", "attr" : "bar" }
{ "_id" : ObjectId("5694ca53d4c65e923780f296"), "name" : "bar2", "attr" : "bar" }
如果要获取每个属性组的最新记录,可以执行以下操作:

> db.content.aggregate({$group: {_id: '$attr', name: {$last: '$name'}}})
{ "_id" : "bar", "name" : "bar2" }
{ "_id" : "foo", "name" : "foo2" }
我想让我的数据按
attr
分组,然后按
\u id
排序,这样每个组中只保留最新的记录,这就是我可以实现的方法。但是我需要一种方法来避免在结果中命名我想要的所有字段(在本例中为“name”),因为在我的实际用例中,它们在前面是未知的

那么,有没有一种方法可以实现这一点,但不必使用
$last
显式地命名每个字段,而只需使用所有字段?当然,我会在分组之前对数据进行排序,我只需要告诉Mongo“从最新的数据中获取所有值”。

查看一些可能的选项:

  • 对您输入的每个属性值执行多个find().sort()查询 想要搜索
  • 获取$last doc的原始_id,然后对每个值执行findOne()(这是一个更具扩展性的选项)
  • 使用系统变量,如图所示
这不是最快的操作,但我假设您更多地将其用于分析,而不是响应用户行为

编辑以添加slouc在评论中发布的示例:
db.content.aggregate({$group:{u id:'$attr',lastItem:{$last:$$ROOT“}}}})

前面未知的字段名是MongoDB中的反模式,会导致各种无法解决的问题,应尽可能避免。它们不是完全任意的,只是我有一个可以属于两个类别之一的项目集合。就像一个包含卡车和汽车的“车辆”集合。我是否应该重新组织它,使集合中的所有记录中的所有字段都完全相同?MongoDB的无模式特性允许您拥有“可选”字段,这些字段仅存在于特定类型的文档中,但当您拥有在不同类型中表示相同内容的字段时,它们应该具有相同的名称。否则,您会遇到这个(以及许多其他)问题。不,在不同类型中没有表示相同内容的字段。我的两种类型的项在70%的属性中重叠,其余的是可选的,并且特定于每种类型。但我希望在我的服务中避免对属性名称进行逻辑和硬编码。如果可能的话,我想学习“一切皆有”。我不知道$$ROOT,这对我很有帮助。其他示例:db.content.aggregate({$group:{{u id:'$attr',lastItem:{$last:$$ROOT'}})。请注意,如果您使用的是ReactiveMongo(就像我一样),则只需要使用一个美元符号。