Add more accurate hashtag search (#11579)
* Add more accurate hashtag search Using ElasticSearch to index hashtags with edge n-grams and score them by usage within the last 7 days since last activity. Only hashtags that have been reviewed and are listable can appear in searches, unless they match the query exactly * Fix search analyzer dropping non-ascii characters
This commit is contained in:
parent
3a77090d01
commit
cc0a55cf9a
10 changed files with 149 additions and 13 deletions
|
@ -13,6 +13,8 @@
|
|||
# listable :boolean
|
||||
# reviewed_at :datetime
|
||||
# requested_review_at :datetime
|
||||
# last_status_at :datetime
|
||||
# last_trend_at :datetime
|
||||
#
|
||||
|
||||
class Tag < ApplicationRecord
|
||||
|
@ -33,7 +35,8 @@ class Tag < ApplicationRecord
|
|||
scope :unreviewed, -> { where(reviewed_at: nil) }
|
||||
scope :pending_review, -> { unreviewed.where.not(requested_review_at: nil) }
|
||||
scope :usable, -> { where(usable: [true, nil]) }
|
||||
scope :discoverable, -> { where(listable: [true, nil]).joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).order(Arel.sql('account_tag_stats.accounts_count desc')) }
|
||||
scope :listable, -> { where(listable: [true, nil]) }
|
||||
scope :discoverable, -> { listable.joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).order(Arel.sql('account_tag_stats.accounts_count desc')) }
|
||||
scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) }
|
||||
|
||||
delegate :accounts_count,
|
||||
|
@ -44,6 +47,8 @@ class Tag < ApplicationRecord
|
|||
|
||||
after_save :save_account_tag_stat
|
||||
|
||||
update_index('tags#tag', :self) if Chewy.enabled?
|
||||
|
||||
def account_tag_stat
|
||||
super || build_account_tag_stat
|
||||
end
|
||||
|
@ -121,9 +126,10 @@ class Tag < ApplicationRecord
|
|||
normalized_term = normalize(term.strip).mb_chars.downcase.to_s
|
||||
pattern = sanitize_sql_like(normalized_term) + '%'
|
||||
|
||||
Tag.where(arel_table[:name].lower.matches(pattern))
|
||||
.where(arel_table[:score].gt(0).or(arel_table[:name].lower.eq(normalized_term)))
|
||||
.order(Arel.sql('length(name) ASC, score DESC, name ASC'))
|
||||
Tag.listable
|
||||
.where(arel_table[:name].lower.matches(pattern))
|
||||
.where(arel_table[:name].lower.eq(normalized_term).or(arel_table[:reviewed_at].not_eq(nil)))
|
||||
.order(Arel.sql('length(name) ASC, name ASC'))
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
end
|
||||
|
|
|
@ -17,6 +17,9 @@ class TrendingTags
|
|||
increment_historical_use!(tag.id, at_time)
|
||||
increment_unique_use!(tag.id, account.id, at_time)
|
||||
increment_vote!(tag, at_time)
|
||||
|
||||
tag.update(last_status_at: Time.now.utc) if tag.last_status_at.nil? || tag.last_status_at < 12.hours.ago
|
||||
tag.update(last_trend_at: Time.now.utc) if trending?(tag) && (tag.last_trend_at.nil? || tag.last_trend_at < 12.hours.ago)
|
||||
end
|
||||
|
||||
def get(limit, filtered: true)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue