in core/search/src/main/kotlin/io/klibs/core/search/ProjectSearchRepositoryJdbc.kt [81:192]
override fun find(
rawQuery: String?,
platforms: List<PackagePlatform>,
targetFilters: Map<TargetGroup, Set<String>>,
ownerLogin: String?,
sortBy: SearchSort,
tags: List<String>,
markers: List<String>,
page: Int,
limit: Int
): List<SearchProjectResult> {
val isQueryPresent = rawQuery?.isBlank() == false
val offset = limit * (page - 1)
val orderBy = when {
sortBy == SearchSort.RELEVANCY && isQueryPresent -> "weighted_rank DESC"
sortBy == SearchSort.MOST_STARS -> "stars DESC"
else -> "stars DESC"
}
val exactMatchQuery = rawQuery?.normalizeSearchQuery()
val exactMatchWildcardQuery = rawQuery?.normalizeSearchQuery()?.addWildcardPostfix()
val (wildcardQueryWithSpecialSymbols, wildcardQueryWithoutSpecialSymbols) = rawQuery?.let {
createWildcardSubqueries(
it
)
} ?: Pair("", "")
val targetCondition = formTargetCondition(targetFilters)
val sql = buildString {
append("SELECT project_id, owner_type, owner_login, name, stars, license_name, latest_version")
append(", latest_version_ts, array_to_string(platforms, ',') AS platforms, plain_description, tags, markers")
// For debugging and testing purposes
append(", targets_vector")
if (isQueryPresent && sortBy == SearchSort.RELEVANCY) {
append(
", (ts_rank_cd(fts, :exactMatchQuery ::tsquery) * 0.7 + " +
"ts_rank_cd(fts, :wildcardQueryWithSpecialSymbols ::tsquery || wildcardQueryWithoutSpecialSymbols || :exactMatchWildcardQuery ::tsquery) * 0.3 + " +
"log(stars + 1) * 0.7) AS weighted_rank"
)
}
appendLine(" FROM project_index")
var prefix = "WHERE"
if (isQueryPresent) {
appendLine(", to_tsquery('english', :wildcardQueryWithoutSpecialSymbols) wildcardQueryWithoutSpecialSymbols")
appendLine(
" WHERE (:wildcardQueryWithSpecialSymbols ::tsquery || wildcardQueryWithoutSpecialSymbols || :exactMatchWildcardQuery ::tsquery) @@ fts"
)
prefix = "AND"
}
if (platforms.isNotEmpty()) {
val platformsQuery = platforms.distinct().joinToString(separator = " & ") { it.name }
appendLine(" $prefix platforms_vector @@ '$platformsQuery'")
prefix = "AND"
}
if (ownerLogin != null) {
appendLine(" $prefix owner_login = :ownerLogin")
prefix = "AND"
}
if (tags.isNotEmpty()) {
appendLine(" $prefix tags @> ARRAY[:tags]::text[]")
prefix = "AND"
}
if (markers.isNotEmpty()) {
appendLine(" $prefix markers && :markers::varchar[]")
prefix = "AND"
}
if (targetCondition != null) {
appendLine(" $prefix targets_vector @@ $targetCondition")
prefix = "AND"
}
if (targetFilters.containsKey(TargetGroup.JavaScript)) {
appendLine(" $prefix platforms_vector @@ 'JS'")
prefix = "AND"
}
if (targetFilters.containsKey(TargetGroup.Wasm)) {
appendLine(" $prefix platforms_vector @@ 'WASM'")
}
appendLine(" ORDER BY $orderBy")
appendLine(" LIMIT $limit")
appendLine(" OFFSET $offset")
}
@Suppress("SqlSourceToSinkFlow")
return jdbcClient.sql(sql)
.param("exactMatchQuery", exactMatchQuery)
.param("exactMatchWildcardQuery", exactMatchWildcardQuery)
.param("wildcardQueryWithSpecialSymbols", wildcardQueryWithSpecialSymbols)
.param("wildcardQueryWithoutSpecialSymbols", wildcardQueryWithoutSpecialSymbols)
.param("ownerLogin", ownerLogin)
.param("tags", tags.toTypedArray())
.param("markers", markers.toTypedArray())
.query(PROJECT_OVERVIEW_ROW_MAPPER)
.list()
}