Java ElasticsearchClient: Conditionally mapping result hits to a certain object depending on a field or index

Using the Java ElasticsearchClient, is it possible to create a custom mapper, so that depending on a certain field (or index) of the result hit, a different object is mapped?

I have several indices with different, but very similar documents. The base properties are the same in all of them. And if I query for a list of IDs, I ususally query for (similar) objects in different indices. Ideally I want to have a result list List<? extends BaseDocument> with potentially different objects in it, all of them extending my BaseDocument.

Of course, one approach would be to this in my BaseDocument, which will store all unmapped properties in a map.

@JsonAnyGetter
@JsonAnySetter
protected final Map<String, Object> properties = new LinkedHashMap<>();

And then, in SpecialDocument, I can access those properties by

public getSpecialProperty() {
    return super.properties.get("specialProperty");
}

Another way would be to map all result hits just to a Map, and then checking the contents of the map and using a custom ObjectMapper to map this map back to my domain objects:

	public List<? extends BaseDocument> search(final List<String> indices, final Query query) throws IOException {
		final ObjectMapper objectMapper = new ObjectMapper();
		final SearchResponse<Map> searchResponse = elasticsearchClient.search(s -> s.index(indices).query(query), Map.class);
		return searchResponse.hits().hits().stream().map(
			hit -> {
				switch (hit.source().get("documentType").toString()) {
					case "specialDocument":
						return objectMapper.convertValue(hit.source(), SpecialDocument.class);
					case "anotherSpecialDocument":
						return objectMapper.convertValue(hit.source(), AnotherSpecialDocument.class);
					default:
						return new BaseDocument();
				}
			}
		).toList();
	}

Now, this is mapping the result twice, one time to a Map, another time to a concrete object.

Is there a way to pass a mapper to the ElasticsearchClient (instead of the JsonpMapper, for example?), where I can define conditions to map the result directly to a certain object, instead of treating all results as the same?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.