在Spring Data MongoRepository中为每个属性值选择1个项目

时间:2016-04-08 10:11:09

标签: java spring mongodb spring-data spring-mongodb

我在MongoDB中有一组对象,并且正在使用Spring Data 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查询是否可行? 我很感激任何帮助。

1 个答案:

答案 0 :(得分:1)

使用聚合框架是可能的。运行以下聚合操作以获得所需的结果:

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

然后可以将上述本机聚合操作转换为Spring Data 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);