当前位置: 首页 > 知识库问答 >
问题:

具有复合ID的spring数据mongodb聚合

凤柏
2023-03-14

我在使用聚合框架从MongoDB读取文档时遇到了问题:我的结果中总是得到空ID。这只发生在具有复合ID的文档中。我尝试了各种版本的spring-data-mongob(1.10.12, 2.0.7),结果相同。

实体定义类

    @Document(collection="entities")
    public class MyEntity {
    static class CompositeKey implements Serializable {
        private String stringKey;

        private Integer intKey;

        public CompositeKey(String stringKey, Integer intKey) {
            this.stringKey = stringKey;
            this.intKey = intKey;
        }

        public Integer getIntKey() {
            return intKey;
        }

        public String getStringKey() {
            return stringKey;
        }

        public String toString() {
            return "{" + stringKey + " - " + intKey + "}";
        }
    }

    @Id
    private CompositeKey id;

    private String param;

    public MyEntity() {}

    public MyEntity(String stringKey, Integer intKey) {
        id = new CompositeKey(stringKey, intKey);
    }

    public CompositeKey getId(){
        return id;
    }

    public void setId(CompositeKey id) {
        this.id = id;
    }

    public String getParam() {
        return param;
    }

    public void setParam(String param) {
        this.param = param;
    }
}

测试代码

public static void main(String[] args) {        
    MongoClient client = new MongoClient("127.0.0.1");
    SimpleMongoDbFactory factory = new SimpleMongoDbFactory(client, "aggTest");
    MongoTemplate mongoTemplate = new MongoTemplate(factory);

    MyEntity entity = new MyEntity();
    entity.setId(new MyEntity.CompositeKey("one", 1));
    entity.setParam("param1");
    mongoTemplate.save(entity);

    entity = new MyEntity();
    entity.setId(new MyEntity.CompositeKey("two", 2));
    entity.setParam("param2");
    mongoTemplate.save(entity);

    Criteria crit = Criteria.where("param").ne("param3");
    List<AggregationOperation> aggOpList = new ArrayList<AggregationOperation>();
    aggOpList.add(Aggregation.match(crit));

    System.out.println("Documents fetched with find: ");        
    for (MyEntity aggResult : mongoTemplate.find(new Query(crit), MyEntity.class).toArray(new MyEntity[0]))
        System.out.println(aggResult.getId() + " - " + aggResult.getParam());

    System.out.println("\nDocuments fetched with aggregate: ");        
    TypedAggregation<MyEntity> aggregation = new TypedAggregation<>(MyEntity.class, aggOpList);
    AggregationResults<MyEntity> aggregate = mongoTemplate.aggregate(aggregation, MyEntity.class);      
    for (MyEntity aggResult : aggregate.getMappedResults())
        System.out.println(aggResult.getId() + " - " + aggResult.getParam());       
}

输出

Documents fetched with find: 
{one - 1} - param1
{two - 2} - param2

Documents fetched with aggregate: 
null - param1
null - param2

调试到以下方法MappingMongoConverter。read(final mongopersistenentity entity、final Document bson、final ObjectPath path)我发现在第一种情况下(find method),documentAccessor变量有以下内容

文档{{u id=Document{{stringKey=one,intKey=1}},param=param1,\u class=MyEntity}

而在第二种情况下(聚合查询),它看起来像

文档{{stringKey=one, intKey=1,参数=参数1,_class=MyEntity}}

文档以某种方式变平,这使得转换器无法填充ID字段。我一定是做错了什么事,但是呢?

共有1个答案

马泰
2023-03-14

Spring数据MongoDB低于3。x自动展平复合id(复合id下的字段被展开并放置在根对象上)。在3.0版以后的版本中删除了此选项:https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#new-功能。3

 类似资料:
  • 有人知道如何使用Spring-Data将下面的聚合函数转换成java代码吗?

  • 有人能帮我把这个mongoDB聚合转换成Spring数据mongo吗? 我试图在每个邀请函文件中获得未提醒与会者的电子邮件列表。 让它在mongo shell中运行,但需要在Spring data mongo中运行。 我的shell查询 ) 正如你们所看到的,这是我提出的,它在管道的项目和团队运作中并没有像预期的那样发挥作用。下面给出了生成的查询。 聚合对象创建 它创建以下查询 聚合对象生成的查询

  • 我的应用程序使用Spring数据MongoDB,我试图在嵌入式文档中按降序排序数据,这是不工作的。 请参考以下JSON文档 JSON-库存文件: Spring数据Mongodb聚合查询: 电流输出: 苹果:150.0 李子:200.0 橙子:500.0 预期产量(按需求描述订单): 橙子:500.0 李子:200.0 苹果:150.0 你能帮我按降序得到预期的输出吗? 此外,我计划通过使用上述带限

  • 我使用复合和术语聚合来获得基于给定字段的分组结果。我还使用基数聚合来获取聚合桶的总计数。 下面是我发送的请求查询,以获得相应的响应: 请求: 答复: 我使用Kibana检查查询,它对我来说很好。 但是,我不确定如何在我的NEST对象语法中使用这个基数聚合器。 这是我的代码: 我将非常感谢任何帮助。

  • 我使用Spring(引导)2.2.7与mongoDB 4.0运行在Debian Stretch(9.12)。我已经设置了3个集合,我试图通过聚合查找级联操作加入这些集合。 操作(节点类) 股票(组件类) 目录(产品类) 每个类都有一个将它们链接在一起的uuid字符串属性。 节点(传感器、接收器、基站等) 组件(带有序列号、条形码的交付产品…) 产品(市场人工制品) 在mongo shell中运行此

  • 我有一种情况,我需要根据一个数组值执行一个group by操作,该数组值将字段值的出现次数相加。然后对计数进行过滤,并准备结果,以便根据条件显示结果。从本质上讲,文档被转换回如果您只使用find函数就会呈现的方式。由于matchedDocuments数组中收集的项的数量,我遇到了临时文档太大的问题。任何关于如何改进这一点的建议都将是有益的。 以下是一些示例文档和基于上述标准的预期结果: