Mongodb 查找各组中最新的并在 Spring boot 中实现

Posted

技术标签:

【中文标题】Mongodb 查找各组中最新的并在 Spring boot 中实现【英文标题】:Mongodb find the latest of each group and implemented in Spring boot 【发布时间】:2020-08-25 16:34:25 【问题描述】:

我是 mongodb 的新手。假设我在一个集合中有文档:

  [
        
          _id: ObjectId("1"),
          uid: "test",
          obj: Object
                    name: "a",
                    field1: "..."
        ,

        
          _id: ObjectId("2"),
          uid: "test",
          obj: Object
                    name: "a",
                    field1: "..."
        ,
        
          _id: ObjectId("3"),
          uid: "test",
          obj: Object
                    name: "b",
                    field1: "..."
        ,
         
          _id: ObjectId("4"),
          uid: "test2",
          obj: Object
                    name: "b",
                    field1: "..."
        
    ]

我想检索具有唯一 obj.name 的 obj 列表,预期输出为:

  [
      
         _id: ObjectId("2") // not really necessary , just to show that the obj was under ObjectId("2")
         name: "a",
         field1: "..."
      ,
      
         _id: ObjectId("3") // not really necessary , just to show that the obj was under ObjectId("3")
         name: "b",
         field1: "..."
      
    ]

我的想法:

    先匹配uid 按 _id desc 对结果进行排序

    按 obj.name 分组

    [ $匹配: uid:“测试” , $排序: _id:-1 , $组: _id: "$obj.name" ]

我得到了什么:


  _id:"a"
,

  _id:"b"

第二个问题: 如何使用 Spring Boot mongo 模板或其他 Spring Boot mongo 库进行此类查询?

 Public class A 
       private String _id;
       private String uid;
       private Obj obj;
    

    Public class Obj 
           private String name;
           private String field1;
    

在 Java 意义上,我想检索 List<Obj>

但不知道该怎么做。

非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

这很简单。关注tutorial。

添加以下代码:

//Add this code to your service class
@Autowired
private MongoTemplate mongoTemplate;

...

//Aggregation pipeline    
Aggregation agg = Aggregation.newAggregation(
    Aggregation.match(Criteria.where("uid").is("test")),
    Aggregation.sort(Direction.DESC, "_id"),
    Aggregation.group("obj.name").first("obj").as("obj"),
    Aggregation.replaceRoot("obj")
);

AggregationResults<Obj> result = mongoTemplate.aggregate(agg, "collection", Obj.class).getMappedResults();
//result.forEach(System.out::println);

【讨论】:

感谢您的回答。我想问一下我的 obj 类是否有多个字段,我需要为每个字段使用 .first 还是有办法用一个函数获取所有字段? @Aerondight 您可以使用$first 运算符获得整个obj。然后,您需要添加额外的Aggregation.replaceRoot() 阶段。再次检查我的答案。

以上是关于Mongodb 查找各组中最新的并在 Spring boot 中实现的主要内容,如果未能解决你的问题,请参考以下文章

Oracle:查询各组最新的一条记录

在 Spring Boot Mongodb 中使用聚合框架按计数查找组

在 MongoDB for Spring 中的 @DBref 列表项中查找/删除

各组评论总结

从String到ObjectId的Spring数据MongoDb聚合查找

各组对我们的意见汇总