-
Notifications
You must be signed in to change notification settings - Fork 1.3k
DATAES630 - Remove GetResultMapper and friends from core package. #331
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
DATAES630 - Remove GetResultMapper and friends from core package. #331
Conversation
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 very much like the direction where the PR is heading to. I added a few comments where I spotted things we need to address.
I'm also wondering regarding the current setup for search result mapping. @Score
is a read-only feature and @ScriptedField
seems also only useful during reads.
What if we consider in a future version projection of search results in the sense that query(…)
methods are able to return an interface and domain objects are no longer required to use @Score
.
Something along the lines of:
interface PersonSerarchHit {
String getFirstName(); // maps to firstName field
@Score
float getScore(); // maps to synthetic score field
}
List<PersonSerarchHit> hits = template.query(query, Person.class, PersonSerarchHit.class);
@ScriptedField("foo")
seems to correspond with @Value("#root.foo")
so we might want to deprecate @ScriptedField
once we can provide proper SpEL support.
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class); | ||
|
||
protected ElasticsearchConverter elasticsearchConverter; | ||
protected MappingElasticsearchConverter elasticsearchConverter; |
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.
Let's stick with ElasticSearchConverter
(the interface) here and gradually explore which functionality we require that we might need to add to the converter interface.
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.
done.
|
||
protected String buildMapping(Class<?> clazz) { | ||
protected MappingElasticsearchConverter createElasticsearchConverter() { | ||
MappingElasticsearchConverter mappingElasticsearchConverter = new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext()); |
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.
We probably want to hold on to a reference of the mapping context ( MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext
) in the instance.
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.
keep the reference in the AbstractElasticsearchTemplate
?
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.
In the *Template
classes we can laways get the MappingContext
from the ElasticsearchConverter
if needed
@@ -1440,7 +1410,7 @@ private IndexRequest prepareIndex(IndexQuery query) { | |||
} else { | |||
indexRequest = new IndexRequest(indexName, type); | |||
} | |||
indexRequest.source(resultsMapper.getEntityMapper().mapToString(query.getObject()), | |||
indexRequest.source(elasticsearchConverter.mapToString(query.getObject()), |
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.
Related: Do we already have a ticket to get rid of the mapToString(…)
method? I was wondering whether we can reuse our Document
API here.
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.
removed it.
@@ -36,11 +35,10 @@ | |||
* @author Artur Konczak | |||
* @author Christoph Strobl | |||
* @author Mark Paluch | |||
* @author Peter-Josef Meisch | |||
*/ | |||
public interface ResultsMapper extends SearchResultMapper, GetResultMapper, MultiGetResultMapper { |
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.
Can we get rid of this type and all …ResultMapper
interfaces?
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.
Did this. There are tests in ElasticsearchTemplateTests
which rely on custom result mappers, especially checking the highlight result or request. I uncommented these so the builds don't fail, but added todos to them, because they have to be checked.
@@ -649,7 +674,134 @@ private boolean isSimpleType(Class<?> type) { | |||
return conversions.isSimpleType(type); | |||
} | |||
|
|||
// --> OHTER STUFF | |||
@Override | |||
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) { |
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.
SearchResponse
should be ideally wrapped into Document
(SearchDocument
). This functionality pulls in ES-specific API into the conversion layer. I'd suggest handling SearchDocument
here only in an EntityReader
fashion. Construction of the Page
object should happen ideally in a utility that is closer to the actual template.
In several stores, we don't even provide paging on the Template API level, only through repositories.
See for reference:
private <T> void populateScriptFields(T result, SearchHit hit) { | ||
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) { | ||
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) { | ||
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class); |
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 is a candidate for cleanup!
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 will be rewritten once we have the SearchHit<T>
in place, the scripted fields should go in there
} | ||
|
||
@Override | ||
public <T> T mapResult(GetResponse response, Class<T> clazz) { |
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 should also accept only Document
.
setPersistentEntityId(result, response.getId(), clazz);
setPersistentEntityVersion(result, response.getVersion(), clazz);
should ideally reside in readObject(…)
return list; | ||
} | ||
|
||
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) { |
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.
These methods are easier to implement in the context of readEntity
and ElasticsearchPersistentEntity
since we already the appropriate context there.
8c01166
to
5f8aad1
Compare
I now cleaned up the ResultMappers, the next thing will be cleaning up the whole bunch of map methods in the |
Another thought about what you wrote about returning the additional info for search results like the score or scripted fields- there is also the highlight info -: Couldn't we introduce a |
5f8aad1
to
f2d1cbb
Compare
No need to tackle the annotation-based aspects here, it was something that I noticed during the review. We can keep the implementations of the mappers for now in the converter, but we should address these. Regarding the search results, we have a similar setup with For repositories, we can be more lenient about the API: Users can either declare a query method returning |
165e3f1
to
468af72
Compare
I removed all the elasticsearch stuff from the In the Converter I renamed the I added a first small test implementation of We could move all the stuff like fields that are not in the entity (scripted), score, highlight and whatever else is coming from Elasticsearch into the Two questions about the
|
One more thought: I introduced |
Spring Data Commons ships with Re:
We should ask rather whether that method should be exposed on the repository in the first place. |
2bc27f6
to
4ce10d9
Compare
I removed the tests that were using a custom EntityMapper to extract the highlights; that will be addressed in a different ticket for the |
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, looks good to me and also this PR is sort of overripe (überreif). Sometimes changes get to the point where looking over the change makes it typically worse so it makes sense to wrap up this ticket and continue with items that popped out of this effort.
* Get the configured {@link ProjectionFactory}. <br /> | ||
* <strong>NOTE</strong> Should be overwritten in implementation to make use of the type cache. | ||
* | ||
* @since 3.2 |
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.
Nit: 4.0
4ce10d9
to
5ac7efe
Compare
This is a draft PR not ready to be merged.
@mp911de I have moved the ResultMapper stuff into
MappingElasticsearchConverter
and cleaned up some stuff.Can you check if this what you thought about the rewriting of the mapping? There still is quite some cleanup to be done, refactoring, poilshing etc, but I'd like to have your feedback before going on.