在Spring数据mongodb中从同一个POJO创建两个集合

时间:2018-04-26 11:06:11

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

用例:我希望有两个具有相同字段的集合。一个集合将包含最新数据(比如说15天),而其他集合则包含旧数据(比如说最近6个月)。 我想用一个POJO实现这个目标,因为它更容易根据日期进行查询,然后将其转换为VO。

底线:我想从1个POJO创建2个集合。

请建议。

2 个答案:

答案 0 :(得分:0)

  1. 考虑到你有类似的POJO

    @Document(collection = "domain")
    public class Domain {
    
        @Id
        private long id;
    
        @Indexed(unique = true)
        private String name;
    
        private Date createdDate;
    
        //getters and setters 
    }
    
  2. 您可以在QueryMethods中编写Repo以从POJO中提取条件数据

    public interface DomainRepository extends MongoRepository<Domain, Long> {
    
        Domain findFirstByName(String domain);
    
        List<Domain> findByCreatedDateBetween(Date thresholdDate1, Date thresholdDate2);
    
    }
    
  3. 在控制器/方法中调用QueryMethods以获得所需内容 集合

    @Autowired
    DomainRepository domainRepo;
    
    List<Domain> 15daysOld = domainRepo.findByCreatedDateBetween(15daysOldDate, currentDate);
    List<Domain> 6monthsOld = domainRepo.findByCreatedDateBetween(6monthsOldDate, currentDate);
    

答案 1 :(得分:0)

我遇到了同样的问题。我认为这不容易实现,因为集合名称是在位于 POJO 上的 @Document 注释中设置的。可以使用 SpEL 表达式动态更改它(参见例如 How To Configure MongoDb Collection Name For a Class in Spring Data),并且有一些示例可以将其用于 multi-tenancymultiple principles 但我不知道如何在编译时使用它从同一个类创建两个不同的 bean。据我所知,这是不可能的。

我可以提供可能的解决方案,但两者都很丑陋。

  1. 这是我实际使用的解决方法。为文档创建子类并将实际逻辑放入父类

父类

@Getter
@FieldDefaults(makeFinal=true, level= AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@ToString
@EqualsAndHashCode
public class CommonParent {

    @Id
    @Delegate
    HourlySiteWaiterRevenue.Key key;
    long count;
    @Field(targetType = FieldType.DECIMAL128)
    BigDecimal sum;

    @CompoundIndex
    @Value
    public static class Key implements Serializable {
        @NonNull UUID entityId;
        @NonNull Instant timestamp;
    }
}

存储库的实际模型

@Document
public class UseThisForRepository extends CommonParent{
    public UseThisForRepository(@NonNull @JsonProperty("key") CommonParent.Key key,
            @NonNull @JsonProperty("count") long count,
            @NonNull @JsonProperty("sum") BigDecimal sum,) {
        super(key, count, sum);
    }
}

存储库的模型完全由样板代码组成,这些代码必须多次复制粘贴,以便您可以拥有多个 @Document 注释。这将默认使用子类名称作为集合名称,但可以在任何地方配置。

  1. mongoTemplate 原则上具有集合名称的重载。可以在 mongoTemplate 中配置集合名称(参见例如 https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template)。应该可以有不同的集合名称并使用它们。但是,我想不出如何在 Spring 从 @Repository 接口自动生成的类中使用这个名称。您可以覆盖 RepositoryCustom 实现中的每一个存储库方法,但是您根本不能使用 @Repository