-
Notifications
You must be signed in to change notification settings - Fork 1.3k
#1218 - Add routing parameter to ElasticsearchOperations. #562
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
Conversation
7e2a1c1
to
8b23548
Compare
af3e97d
to
652a7df
Compare
b768007
to
9b6fbad
Compare
@mp911de after our last call I reworked this. The configuration of the routing is not an parameter in The value of this annotation is not a fixed routing value. This would not make sense. Resolving the routing for an entity is done by a
|
9b6fbad
to
3c87483
Compare
3c87483
to
379e973
Compare
@mp911de if you find the time to have a look… |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks much cleaner now, good work. I left a few comments, mostly about the design of the routing resolver. Resolution means in that context to obtain the value from the context. I think splitting out more methods to make the routing more null-safe makes a lot of sense. Also, take a look at the design of TypeAliasAccessor
and Alias
to represent the absence of a defined routing key.
src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java
Outdated
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java
Outdated
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java
Outdated
Show resolved
Hide resolved
.../java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java
Outdated
Show resolved
Hide resolved
* @since 4.2 | ||
*/ | ||
@Nullable | ||
String getRouting(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should return the evaluated expression (when using SpEL) or the routing string (when using literals).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. this is the value of the @Routing
annotation that is defined on the entity class. Do you mean this should return a SpEL expression? To evaluate the expression this would need the entity, that's what resolveRouting
is for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this method, the persistent entity now only has the resolveRouting()
method, that now contains the complete logic.
*/ | ||
@Override | ||
@Nullable | ||
public String getRouting(@Nullable Object bean, @Nullable String routing) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is either called without or with a bean for two well-defined cases.
I'd suggest to have two distinct methods getRouting(Class)
and getRouting(Class, Object)
. Handing in the routing argument leaks the fact that routing can be defined on the type already. Maybe it would even make sense to have getRouting(IndexCoordinates)
as all these calls to routingResolver.getRouting(null, null)
are dealing with null
in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now have getRouting()
for the fixed-value case and getRouting(object bean)
. So it's no longer possible dot use a lambda for routingResolver
in operations.withRouting(routingResolver)
, but with RoutingResolver.just(fixedValue)
this is ok.
src/main/java/org/springframework/data/elasticsearch/core/routing/package-info.java
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/routing/RoutingResolver.java
Show resolved
Hide resolved
379e973
to
64690cf
Compare
@mp911de 👋 ready for another round… |
d531056
to
4a990e9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a few minor things to consider. I'm still not decided whether SpEL resolution inside the PersistentEntity
is the best approach vs. external annotation lookup. Let's stick with the current design and see how it goes.
src/main/java/org/springframework/data/elasticsearch/core/routing/RoutingResolver.java
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/routing/RoutingResolver.java
Outdated
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolver.java
Outdated
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolver.java
Outdated
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolver.java
Outdated
Show resolved
Hide resolved
src/main/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolver.java
Outdated
Show resolved
Hide resolved
* @return routing value, may be {@literal null} | ||
*/ | ||
@Nullable | ||
String resolveRouting(Object bean); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, bean
should be of type T
. I think there's a similar constrain when obtaining PersistentPropertyAccessor
. Interestingly, isNew(…)
accepts Object
.
Given the way how this method is used, it's fine to keep Object
here and add a type assertion inside the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert to what type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That bean
is instance of T
(the entity type).
a0286a0
to
07bbe65
Compare
Waiting for this new feature. If I can help (testing) would be happy to. Thanks! In the meantime, is there a workaround? Should I implement a custom repository? |
07bbe65
to
9cc3300
Compare
3986468
to
5eeeef2
Compare
@mp911de care to have another look? |
5eeeef2
to
75af58d
Compare
|
||
return expression.getValue(context, String.class); | ||
} catch (EvaluationException e) { | ||
LOGGER.warn("could not resolve", e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about throwing an exception instead of silently falling back to null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, this looks pretty decent.
75af58d
to
9882d84
Compare
The
MappingContext
now has aRoutingAccessorFactory
.The
@Document
annotation has arouting
parameter (I call that the routing specification) that will be passed together with the bean to theRoutingAccessorFactory
which then can produce aRoutingAccessor
for the bean.The default implementation first checks if the routing specification is the name of an
PersistentProperty
for the bean. If so, the value of that property will be used for routing. If not, the routing specification will be evaluated as a SpEL expression with the bean as root object, allowing to define some bean that will resolve to a routing value.If this is not enough, a user can set a custom
RoutingAccessorFactory
in theConfigurationSupport
.Where a routing is needed, but no bean/entity available (get/delete by id), I introduced additional methods taking a routing parameter.