How to make elasticsearch java client return Generic type

59 Views Asked by At

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.

1

There are 1 best solutions below

0
Sajad Soltanian On

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.

Actually you might need more control over your java code, instead of getting such a feature from Elasticsearch directly.

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.

public class SearchParam<T> {
    // ...
    @Nullable
    Class<T> resultType;
    // ...
}

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 the t.class (actually with this approach you wont need the .class part anymore).

public <T extends BaseEventBean> List<T> logs(Map<String,String> params, class<T> resultType)