jillesvangurp/kt-search

[FEAT] script based sorting support

Closed this issue · 2 comments

Describe the enhancement

Add support to the script based sorting feature

SearchDSL().apply {
    sort {
        addScript(
            order = SortOrder.ASC,
            type = "number",
            source = "doc['field_name'].value * params.factor;",
            lang = "painless",
            params = mapOf("factor" to 1.1),
        )
    }
}

Why is this needed?

Screen Shot 2024-04-11 at 6 21 50 PM

Sometimes business requirements require complex sorting logic. elastic search query can solve this with script-based sorting(e.g. https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#script-based-sorting), and it would be nice to support this in kt-search as well.
Also, you can query basic field name based sorting and script based sorting in one sort array to handle complex requirements.

How do you think it should be done?

If you add the methods below inside the SortBuilder, you should be able to use them in conjunction with your existing sorting methods.

fun addScript(
    order: SortOrder = SortOrder.DESC,
    type: String,
    source: String,
    params: Map<String, Any>? = emptyMap(),
    lang: String? = null,
) {
    _sortFields.add(
        withJsonDsl {
            this["_script"] = withJsonDsl {
                this["order"] = order.name
                this["type"] = type
                this["script"] = scriptBuilder(source, params, lang)
            }
        },
    )
}

private fun scriptBuilder(
    source: String,
    params: Map<String, Any>? = emptyMap(),
    lang: String? = "painless",
): JsonDsl {
    return withJsonDsl {
        this["source"] = source
        this["lang"] = lang
        if (params?.isNotEmpty() == true) {
            this["params"] = withJsonDsl {
                params.forEach { (key, value) -> this[key] = value }
            }
        }
    }
}

Will you be able to help with a pull request?

Yes

Please go ahead with the PR if you have time.

closed by #131