fix: use ParadeDB v2 fuzzy prefix matching for search (#2346)

Switch from legacy @@@ paradedb.match() to v2 ||| operator with
::pdb.fuzzy(1, t) cast. This enables prefix matching so 'landing'
matches 'landingpages', and adds single-character typo tolerance.
This commit is contained in:
kolaente 2026-03-05 00:12:15 +01:00
parent ee2723d9cf
commit 0a38ec0838
1 changed files with 9 additions and 16 deletions

View File

@ -52,25 +52,18 @@ func MultiFieldSearch(fields []string, search string) builder.Cond {
// for non-ParadeDB queries and the id field for ParadeDB queries.
func MultiFieldSearchWithTableAlias(fields []string, search, tableAlias string) builder.Cond {
if Type() == schemas.POSTGRES && paradedbInstalled {
if len(fields) == 1 {
// Single field search - use optimized match function
return builder.Expr("id @@@ paradedb.match(?, ?)", fields[0], search)
}
// Multi-field search - use disjunction_max for optimal performance
fieldMatches := make([]string, len(fields))
args := make([]interface{}, len(fields)*2)
conditions := make([]builder.Cond, len(fields))
for i, field := range fields {
fieldMatches[i] = "paradedb.match(?, ?)"
args[i*2] = field
args[i*2+1] = search
fieldName := field
if tableAlias != "" {
fieldName = tableAlias + "." + field
}
conditions[i] = builder.Expr(fieldName+" ||| ?::pdb.fuzzy(1, t)", search)
}
idField := "`id`"
if tableAlias != "" {
idField = "`" + tableAlias + "`.`id`"
if len(conditions) == 1 {
return conditions[0]
}
return builder.Expr(idField+" @@@ paradedb.disjunction_max(ARRAY["+strings.Join(fieldMatches, ", ")+"])", args...)
return builder.Or(conditions...)
}
// For non-PostgreSQL databases, use ILIKE on all fields