spring-data-mongodb
spring-data-mongodb copied to clipboard
Map collection and fields for `$lookup`/`$graphLookup` aggregation stage against domain type
Working on a legacy code base, we've got lots of code that builds up aggregations including lookups, so we want to lookup the collection name for a class.
We've got an implementation that I'm guessing was at some point copied from mongo, but doesn't seem up to date and digging through code can assume it was copied from BasicMongoPersistentEntity
public BasicMongoPersistentEntity(TypeInformation<T> typeInformation) {
super(typeInformation, MongoPersistentPropertyComparator.INSTANCE);
Class<?> rawType = typeInformation.getType();
String fallback = MongoCollectionUtils.getPreferredCollectionName(rawType);
if (this.isAnnotationPresent(Document.class)) {
Document document = this.getRequiredAnnotation(Document.class);
this.collection = StringUtils.hasText(document.collection()) ? document.collection() : fallback;
this.language = StringUtils.hasText(document.language()) ? document.language() : "";
this.expression = detectExpression(document.collection());
this.collation = document.collation();
this.collationExpression = detectExpression(document.collation());
} else {
this.collection = fallback;
this.language = "";
this.expression = null;
this.collation = null;
this.collationExpression = null;
}
Is there any reason this isn't exposed as a static method call so anyone can resolve class name to collection name consistently with how mongo does it?
Can you elaborate at which points you need the collection name explicitly? Unless I overlook something (perfectly possible) all our APIs (aggregations included) usually – at least also – take a type parameter where they expose an explicit collection name.
We want to know what the name that is actually going to be used is, even if it didn't have a type parameter. We are required by our company to use Java API, and no literals, so have to build up things like:
Aggregation.lookup(
getCollectionName(Project.class),
Dashboard.FIELD_NAME_PROJECT_ID,
FIELD_NAME_ID_WITH_UNDERSCORE,
FIELD_NAME_PROJECT
);
MongoOperations already exposes getCollectionName.
However, extending the Aggregation API to accept a type parameter for the foreign collection would in my opinion be a nice enhancement to enable something like:
lookup()
.from(User.class)
.localField("id")
.foreignField("firstname")
.pipeline(...
Having the type present would also allow to map the foreignField against it to capture any potential @Field annotations that customize the target field name.