-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
According to the documentation, it is possible to create a time series collection via MongoTemplate by either providing explicit CollectionOptions or a class annotated with @TimeSeries:
@TimeSeries(timeField = "timestamp")
record MyTimeSeries(@Id String id, Instant timestamp, String value) {}
mongoTemplate.createCollection(MyTimeSeries.class)in which case the CollectionOptions are derived from the annotation:
Lines 1058 to 1081 in b8b93bc
| if (entity.isAnnotationPresent(TimeSeries.class)) { | |
| TimeSeries timeSeries = entity.getRequiredAnnotation(TimeSeries.class); | |
| if (entity.getPersistentProperty(timeSeries.timeField()) == null) { | |
| throw new MappingException(String.format("Time series field '%s' does not exist in type %s", | |
| timeSeries.timeField(), entity.getName())); | |
| } | |
| TimeSeriesOptions options = TimeSeriesOptions.timeSeries(timeSeries.timeField()); | |
| if (StringUtils.hasText(timeSeries.metaField())) { | |
| if (entity.getPersistentProperty(timeSeries.metaField()) == null) { | |
| throw new MappingException( | |
| String.format("Meta field '%s' does not exist in type %s", timeSeries.metaField(), entity.getName())); | |
| } | |
| options = options.metaField(timeSeries.metaField()); | |
| } | |
| if (!Granularity.DEFAULT.equals(timeSeries.granularity())) { | |
| options = options.granularity(timeSeries.granularity()); | |
| } | |
| collectionOptions = collectionOptions.timeSeries(options); | |
| } |
However, if you want to create the collection with a custom name (not derived from the class), there is currently no option for deriving the CollectionOptions from the annotation. The only overloads of mongoTemplate.createCollection that take a String collectionName also require explicit CollectionOptions.
Using mongoTemplate.save(value, "myCustomName") is a non-starter since it does not read the entity metadata and just creates a basic collection (not a time series) with no other options.
Custom names are important for several widespread use cases, for example collection-level multi-tenancy, where you would create multiple collection with the same definition to segregate data for different tenants, or any other types of data segmentation.
I propose new methods to create a collection that take both the collectionName and the entityClass as inputs:
public <T> MongoCollection<Document> createCollection(String collectionName, Class<T> entityClass) {
return createCollection(collectionName, entityClass,
operations.forType(entityClass).getCollectionOptions());
}
public <T> MongoCollection<Document> createCollection(String collectionName, Class<T> entityClass,
@Nullable CollectionOptions collectionOptions) {
Assert.notNull(collectionName, "CollectionName must not be null");
Assert.notNull(entityClass, "EntityClass must not be null");
return doCreateCollection(collectionName,
operations.convertToCreateCollectionOptions(collectionOptions, entityClass));
}