Files
fizzy/app/models/search/record/trilogy.rb
T
Donal McBreen b571303385 Don't use Current.account for search records
It doesn't actually work, and even if we could make it work reliably
we are better off if the records always know to go to the right shard.

It does make the interface a bit more complicated as we need to select
the right shard class with `for(account_id)`.
2025-11-25 11:34:41 +00:00

71 lines
1.7 KiB
Ruby

module Search::Record::Trilogy
extend ActiveSupport::Concern
SHARD_COUNT = 16
included do
self.abstract_class = true
before_save :set_account_key, :stem_content
scope :matching, ->(query, account_id) do
full_query = "+account#{account_id} +(#{Search::Stemmer.stem(query)})"
where("MATCH(#{table_name}.account_key, #{table_name}.content, #{table_name}.title) AGAINST(? IN BOOLEAN MODE)", full_query)
end
SHARD_CLASSES = SHARD_COUNT.times.map do |shard_id|
Class.new(self) do
self.table_name = "search_records_#{shard_id}"
def self.name
"Search::Record"
end
end
end.freeze
end
class_methods do
def shard_id_for_account(account_id)
Zlib.crc32(account_id.to_s) % SHARD_COUNT
end
def search_fields(query)
"#{connection.quote(query.terms)} AS query"
end
def for(account_id)
SHARD_CLASSES[shard_id_for_account(account_id)]
end
end
def card_title
highlight(card.title, show: :full) if card_id
end
def card_description
highlight(card.description.to_plain_text, show: :snippet) if card_id
end
def comment_body
highlight(comment.body.to_plain_text, show: :snippet) if comment
end
private
def stem_content
self.title = Search::Stemmer.stem(title) if title_changed?
self.content = Search::Stemmer.stem(content) if content_changed?
end
def set_account_key
self.account_key = "account#{account_id}"
end
def highlight(text, show:)
if text.present? && attribute?(:query)
highlighter = Search::Highlighter.new(query)
show == :snippet ? highlighter.snippet(text) : highlighter.highlight(text)
else
text
end
end
end