[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](https://private-user-images.githubusercontent.com/24601847/321577027-b6347edb-6e30-493a-aca2-b9b42ae0506b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ4OTM1NjksIm5iZiI6MTcyNDg5MzI2OSwicGF0aCI6Ii8yNDYwMTg0Ny8zMjE1NzcwMjctYjYzNDdlZGItNmUzMC00OTNhLWFjYTItYjliNDJhZTA1MDZiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI5VDAxMDEwOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI2NjliOTkwMTcyOTNlNTBmYjAyNWE0NGI0M2E3OGI5OGU1Zjg0YmM2NDhmMzM5MzZmYWU4ODI5NDMyMTRlOTEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.njrfgu5I3nJOpOnB48mVi6PAJKBXDswEqiff4CmFYMc)
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.