【问题标题】:Spring Mongo Aggregation give a conversion errorSpring Mongo Aggregation 给出转换错误
【发布时间】:2021-11-19 08:26:22
【问题描述】:

我正在尝试使用 Mongo 聚合,但收到一个我不理解的错误。

这是我的域名:

   @Document(collection = "tapes")
   public class Tape {

      @Id
      private String id;

      private String area;

      private Integer tape;

      private String tapeModel;
    
     // follow getters e setters

mongo shell 命令和输出如下:

> db.tapes.aggregate([{ $group: { _id: { "area":"$area"}, tapes: {$push: {tape: "$tape"}}}}  ])
{ "_id" : { "area" : "free" }, "tapes" : [ { "tape" : 1 }, { "tape" : 2 } ] }
{ "_id" : { "area" : "Qnap" }, "tapes" : [ { "tape" : 3 } ] }

以下是在 Spring 中重新创建聚合的尝试:

AggregationOperation group = Aggregation.group("area").push("tape").as("tape");
Aggregation aggregation = Aggregation.newAggregation(group);
AggregationResults<Tape> results = mongoTemplate.aggregate(aggregation, "tapes", Tape.class);
//List<Tape> tapes = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Tape.class), Tape.class).getMappedResults();
List<Tape> tapes = results.getMappedResults();
System.out.println(tapes);

但我收到以下错误:

Cannot convert [3] of type class java.util.ArrayList into an instance of class java.lang.Integer! Implement a custom Converter<class java.util.ArrayList, class java.lang.Integer> and register it with the CustomConversions. Parent object was: it.unifi.cerm.cermadminspring.domain.Tape@2b84da07 -> null
org.springframework.data.mapping.MappingException: Cannot convert [3] of type class java.util.ArrayList into an instance of class java.lang.Integer! Implement a custom Converter<class java.util.ArrayList, class java.lang.Integer> and register it with the CustomConversions. Parent object was: it.unifi.cerm.cermadminspring.domain.Tape@2b84da07 -> null

我不明白为什么,我搜索了聚合示例,所有示例都或多或少与我的相似。

有人可以帮助我吗?

【问题讨论】:

    标签: spring spring-data-mongodb


    【解决方案1】:

    首先,为了让生活更轻松,可以使用更简化的聚合:

    > db.tapes.aggregate([ {$group: {_id: "$area", tapes: {$push: "$tape"}}} ])
    

    应该产生的结果:

    { "_id" : "free", "tapes" : [  1 , 2  ] }
    { "_id" : "Qnap", "tapes" : [  3  ] }
    

    这应该与对 Java group 聚合操作的更改相匹配: AggregationOperation group = Aggregation.group("area").push("tape").as("tapes");
    请注意,我已更改为复数:as("tapes")

    然后,请注意您实际上返回的文档与您在Tape 类中映射的结构不同。该文档包含两个字段,String idList&lt;Integer&gt; tapes 字段。

    这就是我上面建议的简写 group 聚合的原因,以使映射更容易:

    public class TapesForArea {
    
        private String id; // which is the area
    
        private List<Integer> tapes;
    
        // getters, setters ...
    }
    

    您不需要使用spring-data-mongodb 注释映射此类。

    最后,让聚合结果返回正确的类型:

    AggregationResults<TapesForArea> results = 
        mongoTemplate.aggregate(aggregation, "tapes", TapesForArea.class);
    List<TapesForArea> tapes = results.getMappedResults();
    

    顺便说一句,错误来自您尝试将单个项目 tape 数组 [ 3 ] 映射到 Tape 类的 private Integer tape; 属性。

    【讨论】:

    • 非常感谢您的有用解释。
    猜你喜欢
    • 2020-03-15
    • 2022-12-14
    • 2016-12-01
    • 2013-05-15
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    相关资源
    最近更新 更多