Select Spring Data MongoRepository 中每个属性值 1 个项目

Select 1 item per attribute value in Spring Data MongoRepository

我在 MongoDB 中有一个对象集合,并且正在使用 Spring 数据 MongoDB。

我的实体集合看起来像这样:

--------------------------------------------
| id        | snapshot      | name         |
--------------------------------------------
| 2         | somedate      | bla          |
| 2         | somedate      | foo          |
| 3         | somedate      | bar          |
| 3         | somedate      | cheese       |
| 6         | somedate      | milk         |
| 6         | somedate      | lorum        |
| 6         | somedate      | ipsum        |
| 9         | somedate      | do           |
| 10        | somedate      | re           |
| 10        | somedate      | mi           |
| 15        | somedate      | fa           |    
--------------------------------------------

我想获取一个对象列表,其中每个不同的 ID 只有一个对象,该 ID 的对象应该是具有最新日期的对象。

我的结果应该是这样的:

--------------------------------------------
| id        | snapshot      | name         |
--------------------------------------------
| 2         | somedate      | bla          |
| 3         | somedate      | bar          |
| 6         | somedate      | milk         |
| 9         | somedate      | do           |
| 10        | somedate      | mi           |
| 15        | somedate      | fa           |    
--------------------------------------------

使用 MongoRepository 查询是否可行? 如果有任何帮助,我将不胜感激。

有了聚合框架,这是可能的。 运行下面的聚合操作得到想要的结果:

db.collection.aggregate([
    { "$sort": { "snapshot": -1 } },
    {
        "$group": {
            "_id": "$id",
            "snapshot": { "$first": "$snapshot" },
            "name": { "$first": "$name" }
        }
    }
])

然后可以将上面的本机聚合操作转换为 Spring 数据 MongoDB 聚合为:

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

TypedAggregation<Entity> aggregation = newAggregation(Entity.class,
    sort(DESC, "snapshot"),
    group("id")
        .first("snapshot").as("snapshot")
        .first("name").as("name")
);

AggregationResults<EntityStats> result = mongoTemplate.aggregate(aggregation, EntityStats.class);