diff options
author | unarist <m.unarist@gmail.com> | 2017-06-06 23:07:06 +0900 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-06-06 16:07:06 +0200 |
commit | 004672aa6c482b212e36b9e794d107be456a11da (patch) | |
tree | 7bde1904fe421f63adb8210179ec8eb458fe16a3 /app | |
parent | ad4a28f4f689cc9a37a5c2d5dd8c012e964903b7 (diff) |
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.
Diffstat (limited to 'app')
-rw-r--r-- | app/models/tag.rb | 19 |
1 files changed, 3 insertions, 16 deletions
diff --git a/app/models/tag.rb b/app/models/tag.rb index 4001e6ed5..08e3c1b03 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -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 |