0
0
Fork 0

Fix tag search order and not to use tsvector (#3611)

* Sort results by the name
* Switch search method to simple `LIKE` matching instead of tsvector/tsquery

Previously we used scores from ts_rank_cd() to sort results, but it didn't work
because the function returns same score for all results. It's not for calculate
similarity of single words. Sometimes this bug even push out exact matching tag
from results.

Additionally, PostgreSQL supports prefix searching with standard btree index.
Using it offers simpler code, but also less index size and some speed.
This commit is contained in:
unarist 2017-06-06 23:07:06 +09:00 committed by Eugen Rochko
parent ad4a28f4f6
commit 004672aa6c
4 changed files with 26 additions and 18 deletions

View file

@ -21,22 +21,9 @@ class Tag < ApplicationRecord
end
class << self
def search_for(terms, limit = 5)
terms = Arel.sql(connection.quote(terms.gsub(/['?\\:]/, ' ')))
textsearch = 'to_tsvector(\'simple\', tags.name)'
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
sql = <<-SQL.squish
SELECT
tags.*,
ts_rank_cd(#{textsearch}, #{query}) AS rank
FROM tags
WHERE #{query} @@ #{textsearch}
ORDER BY rank DESC
LIMIT ?
SQL
Tag.find_by_sql([sql, limit])
def search_for(term, limit = 5)
pattern = sanitize_sql_like(term) + '%'
Tag.where('name like ?', pattern).order(:name).limit(limit)
end
end
end