I am using elasticsearch java client 8.12 elasticsearch-java lastest version, and I make a search for some fields using the following code:
public List<BaseEventBean> logs(Map<String,String> params) {
SearchResponse<BaseEventBean> response = null;
String[] targetFields = new String[]{
"username", "email", "user_role", "ip_address", "target_type", "country_code"
};
try {
response = client.search(s -> s.index(INDEX).query(q -> q.bool(b -> b.must(prepareParam(params)))).
source(it -> it.filter(item -> item.includes(Arrays.asList(targetFields)))).size(10000), BaseEventBean.class);
} catch (Exception e) {
log.error("SEARCHING PROCESS HAS BEEN FAIL " + e.getMessage());
return null;
}
return response.hits().hits().stream().map(Hit::source).collect(Collectors.toList());
}
and the BaseEventBean class is like the following:
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class BaseEventBean {
@JsonProperty("id")
private String id;
@JsonProperty("event_type")
private String eventTypes;
@JsonProperty("event_description")
private String eventDescription;
@JsonProperty("ip_address")
private String ipAddress;
@JsonProperty("username")
private String username;
@JsonProperty("email")
private String email;
@JsonProperty("user_role")
private String userRole;
@JsonProperty("target_type")
private String targetType;
}
the problem here is, there are subclasses that extends BaseEventBean with additional fields like this:
@Setter
@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public class BlacklistCountriesEventBean extends BaseEventBean {
@JsonProperty("country_code")
private String countryCode;
@JsonProperty("country_name")
private String countryName;
}
if I put the type BaseEventBean Like above it will not map BlacklistCountriesEventBean fields, how can I solve this problem? is there another way or methods that I can use to make elasticsearch return data as is and then I map it? I cannot add fields of sub classes into BaseEventBean because there are so many inheritors and if I do this it will make BaseEventBean very big class with so many fields will not always used.
I don't know how well I have understood the problem. Though as it seems, we have had the same problem in our project and we have kept up with a clean solution for it.
Real Example
We have a search method in which a SearchParam is passed as an argument to it. below is the simplified view of such a class.
So while we want to convert the final document to a class Type we will use the resultType field to do so.
You can also pass such a
Class<T>parameter to your search method, so you can somehow use thet.class(actually with this approach you wont need the.classpart anymore).