Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow creating time series collections with custom name and CollectionOptions derived from annotation #4684

Open
gbaso opened this issue Apr 5, 2024 · 2 comments
Labels
status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged

Comments

@gbaso
Copy link

gbaso commented Apr 5, 2024

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:

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));
	}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 5, 2024
@mp911de
Copy link
Member

mp911de commented Apr 8, 2024

Let me see whether I understand your request correctly. You're looking for a way to create a timeseries collection that derives its CollectionOptions from a Class but you want to specify a custom name?

If so, then this is not possible. We do not expose our utilities that derive information from annotations for application-code usage. These utilities are private and not part of our public API.

You can call however MongoOperations.createCollection(String collectionName, @Nullable CollectionOptions collectionOptions)

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Apr 8, 2024
@gbaso
Copy link
Author

gbaso commented Apr 9, 2024

You're looking for a way to create a timeseries collection that derives its CollectionOptions from a Class but you want to specify a custom name?

Yes, that is correct.

If so, then this is not possible. We do not expose our utilities that derive information from annotations for application-code usage. These utilities are private and not part of our public API.

There is no need to expose those utilities. New overloads for MongoOperations.createCollection would be sufficient.

This is precisely what MongoOperations.createCollection(Class<T> entityClass) already does. Despite the misleading javadoc, it doesn't just derive the collection name from the entity class, it also derives the CollectionOptions, which is very convenient for time series.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants