jhipster / generator-jhipster

JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
https://www.jhipster.tech
Apache License 2.0
21.53k stars 4.02k forks source link

ElasticSearch Sort not active by default #26712

Open swilimo opened 3 months ago

swilimo commented 3 months ago
Overview of the feature request

On latest versions of Jhipster, a lot of code was added to prevent sorting while performing search in ElasticSearch.

This use case was motivated by the fact that "all shards fail" when you try to sort on anything else than a keyword. But this is not intuitive, as most of business cases need a sort on elasticsearch, especially when it is used for listing entities.

Tons of code was added to html / Typescript to delete the sort, while it is not the common use case. It's not dirty in the sense of "clean" code but in term of logic, it has no sense.

The solution would be to add a keyvword as inner field on each one, this works for any type of fields. For instance :

@MultiField( mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "verbatim", type = FieldType.Keyword) } ) private String lastName;

this way we just add on HTML :

<th scope="col" SortBy="lastName.verbatim">

And the sort works

Motivation for or Use Case

Most of business cases need a sort on elasticsearch, especially when it is used for listing entities.

Related issues or PR
OmarHawk commented 3 months ago

Newer elasticsearch versions do generate a keyword field automatically. For my own application, I implemented a Blueprint that enhances the application by allowing to sort on more fields than the default allows by automatically rewriting the Pageable to use that autogenerated .keyword field for sorting for additonal fields instead. ;-)

Something like this:

    /**
     * Creates a new Pageable with the sorting support improved.
     *
     * @param originalPageable
     * @param rootClass
     * @return
     */
    private static Pageable getSortingSupportImprovedPageable(Pageable originalPageable, Class<?> rootClass) {
        List<Sort.Order> orders = new ArrayList<>();
        for (Sort.Order order : originalPageable.getSort()) {
            String property = order.getProperty();
            if (supportsKeywordSearch(property, rootClass)) {
                property += ".keyword";
            }

            orders.add(new Sort.Order(order.getDirection(), property));
        }

        return PageRequest.of(originalPageable.getPageNumber(), originalPageable.getPageSize(), Sort.by(orders));
    }

and the supportsKeywordSearch method allows all String and enum fields, type check using reflection based on the given fieldname (property) and the rootClass.

swilimo commented 3 months ago

Thanks for your answer, that's what i'm saying basically, weather it's your solution to have a method for that, or just by adding innerfield on each property or if a keyword is generated automatically, just replace the sort on html by "name.keyword"

But putting that much code on client side to prevent elastic from sorting while searching has no sense for me at least

OmarHawk commented 3 months ago

Thanks for your answer, that's what i'm saying basically, weather it's your solution to have a method for that, or just by adding innerfield on each property or if a keyword is generated automatically, just replace the sort on html by "name.keyword"

But putting that much code on client side to prevent elastic from sorting while searching has no sense for me at least

The idea of my post was to give an impression what could be a solution for the generator itself with the stuff that is already there. ;-)

swilimo commented 3 months ago

The idea of my post was to give an impression what could be a solution for the generator itself with the stuff that is already there. ;-)

Thanks Omar, i have a question though, couldn't find the answer.

Are there types that you cant sort with your solution ? or either it's sortable or it has automatically generated keyword field ?

When you say newer elasticsearch versions, it is starting 8 ?

I'm asking those questions, because i guess if this is implemented, we need to make sure that it resolves the problem once and for all, either by applying your solution or the innerfield solution. I know the innerfield solution would work with any elasticsearch version (well at least from 6).

Thanks :)

OmarHawk commented 3 months ago

Yes, ES8 works definetely.

Additionally sortable are String and enum types using the .keyword. UUID produces also a String in ES, but that doesn't make sense to sort for...

mraible commented 1 month ago

If y'all have a solution, please submit a PR!