Add fuzzy user search with levenshtein
continuous-integration/drone/push Build is passing Details

pull/15/head
avalin 11 months ago
parent a15b77342b
commit 95184858da

@ -25,6 +25,12 @@ class PostgresDataSource : AllInDataSource() {
dialect = PostgreSqlDialect() dialect = PostgreSqlDialect()
) )
database.execute(
"""
CREATE EXTENSION IF not exists fuzzystrmatch;
""".trimIndent()
)
database.execute( database.execute(
""" """
CREATE TABLE IF not exists users ( CREATE TABLE IF not exists users (

@ -5,12 +5,12 @@ import allin.data.postgres.entities.FriendEntity
import allin.data.postgres.entities.friends import allin.data.postgres.entities.friends
import allin.data.postgres.entities.users import allin.data.postgres.entities.users
import allin.dto.UserDTO import allin.dto.UserDTO
import allin.ext.levenshtein
import allin.ext.toLowerCase import allin.ext.toLowerCase
import allin.model.FriendStatus import allin.model.FriendStatus
import org.ktorm.database.Database import org.ktorm.database.Database
import org.ktorm.dsl.and import org.ktorm.dsl.and
import org.ktorm.dsl.eq import org.ktorm.dsl.eq
import org.ktorm.dsl.like
import org.ktorm.dsl.notEq import org.ktorm.dsl.notEq
import org.ktorm.entity.* import org.ktorm.entity.*
@ -48,6 +48,8 @@ class PostgresFriendDataSource(private val database: Database) : FriendDataSourc
override fun filterUsersByUsername(fromUserId: String, search: String): List<UserDTO> = override fun filterUsersByUsername(fromUserId: String, search: String): List<UserDTO> =
database.users database.users
.filter { (it.username.toLowerCase() like "%$search%") and (it.id notEq fromUserId) } .filter { it.id notEq fromUserId }
.sortedBy { it.username.toLowerCase().levenshtein(search.lowercase()) }
.take(10)
.map { user -> user.toUserDTO(friendStatus = getFriendStatus(fromUserId, user.id)) } .map { user -> user.toUserDTO(friendStatus = getFriendStatus(fromUserId, user.id)) }
} }

@ -3,6 +3,7 @@ package allin.ext
import org.ktorm.database.Database import org.ktorm.database.Database
import org.ktorm.expression.FunctionExpression import org.ktorm.expression.FunctionExpression
import org.ktorm.schema.ColumnDeclaring import org.ktorm.schema.ColumnDeclaring
import org.ktorm.schema.IntSqlType
import org.ktorm.schema.VarcharSqlType import org.ktorm.schema.VarcharSqlType
import java.sql.ResultSet import java.sql.ResultSet
@ -45,4 +46,15 @@ fun ColumnDeclaring<String>.toUpperCase(): FunctionExpression<String> {
arguments = listOf(this.asExpression()), arguments = listOf(this.asExpression()),
sqlType = VarcharSqlType sqlType = VarcharSqlType
) )
} }
fun ColumnDeclaring<String>.levenshtein(target: ColumnDeclaring<String>): FunctionExpression<Int> {
return FunctionExpression(
functionName = "levenshtein",
arguments = listOf(this.asExpression(), target.asExpression()),
sqlType = IntSqlType
)
}
fun ColumnDeclaring<String>.levenshtein(target: String): FunctionExpression<Int> =
levenshtein(wrapArgument(target))
Loading…
Cancel
Save