Fix ES setting for Account Full Text Search
This commit is contained in:
parent
176dd499b7
commit
46d05ea6e8
3 changed files with 110 additions and 2 deletions
|
@ -14,6 +14,8 @@ class AccountsIndex < Chewy::Index
|
|||
},
|
||||
|
||||
sudachi_content: {
|
||||
tokenizer: 'sudachi_tokenizer',
|
||||
type: 'custom',
|
||||
filter: %w(
|
||||
lowercase
|
||||
cjk_width
|
||||
|
@ -22,8 +24,13 @@ class AccountsIndex < Chewy::Index
|
|||
sudachi_baseform
|
||||
search
|
||||
),
|
||||
tokenizer: 'sudachi_tokenizer',
|
||||
},
|
||||
},
|
||||
|
||||
normalizer: {
|
||||
keyword: {
|
||||
type: 'custom',
|
||||
filter: %w(lowercase asciifolding cjk_width),
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -33,6 +40,7 @@ class AccountsIndex < Chewy::Index
|
|||
min_gram: 1,
|
||||
max_gram: 15,
|
||||
},
|
||||
|
||||
sudachi_tokenizer: {
|
||||
type: 'sudachi_tokenizer',
|
||||
discard_punctuation: true,
|
||||
|
@ -61,12 +69,14 @@ class AccountsIndex < Chewy::Index
|
|||
field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content'
|
||||
end
|
||||
|
||||
field :actor_type, type: 'keyword', analyzer: 'content'
|
||||
field :actor_type, type: 'keyword', normalizer: 'keyword'
|
||||
|
||||
field :text, type: 'text', value: ->(account) { account.index_text } do
|
||||
field :stemmed, type: 'text', analyzer: 'sudachi_content'
|
||||
end
|
||||
|
||||
field :discoverable, type: 'boolean'
|
||||
|
||||
field :following_count, type: 'long', value: ->(account) { account.following.local.count }
|
||||
field :followers_count, type: 'long', value: ->(account) { account.followers.local.count }
|
||||
field :subscribing_count, type: 'long', value: ->(account) { account.subscribing.local.count }
|
||||
|
|
54
app/lib/account_filter.rb
Normal file
54
app/lib/account_filter.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AccountFilter
|
||||
attr_reader :target_account, :account
|
||||
|
||||
def initialize(target_account, account, preloaded_relations = {})
|
||||
@target_account = target_account
|
||||
@account = account
|
||||
@preloaded_relations = preloaded_relations
|
||||
end
|
||||
|
||||
def filtered?
|
||||
return false if !account.nil? && account.id == target_account.id
|
||||
(account_present? && filtered_account?) || silenced_account?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account_present?
|
||||
!account.nil?
|
||||
end
|
||||
|
||||
def filtered_account?
|
||||
blocking_account? || blocked_by_account? || blocking_domain? || muting_account?
|
||||
end
|
||||
|
||||
def blocking_account?
|
||||
@preloaded_relations[:blocking] ? @preloaded_relations[:blocking][target_account.id] : account.blocking?(target_account)
|
||||
end
|
||||
|
||||
def blocked_by_account?
|
||||
@preloaded_relations[:blocked_by] ? @preloaded_relations[:blocked_by][target_account.id] : target_account.blocking?(account)
|
||||
end
|
||||
|
||||
def blocking_domain?
|
||||
@preloaded_relations[:domain_blocking_by_domain] ? @preloaded_relations[:domain_blocking_by_domain][target_account.domain] : account.domain_blocking?(target_account.domain)
|
||||
end
|
||||
|
||||
def muting_account?
|
||||
@preloaded_relations[:muting] ? @preloaded_relations[:muting][target_account.id] : account.muting?(target_account)
|
||||
end
|
||||
|
||||
def silenced_account?
|
||||
!account&.silenced? && target_account_silenced? && !account_following_target_account?
|
||||
end
|
||||
|
||||
def target_account_silenced?
|
||||
target_account.silenced?
|
||||
end
|
||||
|
||||
def account_following_target_account?
|
||||
@preloaded_relations[:following] ? @preloaded_relations[:following][target_account.id] : account&.following?(target_account)
|
||||
end
|
||||
end
|
44
app/services/account_full_text_search_service.rb
Normal file
44
app/services/account_full_text_search_service.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AccountFullTextSearchService < BaseService
|
||||
def call(query, account, limit, options = {})
|
||||
@query = query&.strip
|
||||
@account = account
|
||||
@options = options
|
||||
@limit = limit.to_i
|
||||
@offset = options[:offset].to_i
|
||||
|
||||
return if @query.blank? || @limit.zero?
|
||||
|
||||
perform_account_text_search!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def perform_account_text_search!
|
||||
definition = parsed_query.apply(AccountsIndex.filter(term: { discoverable: true }))
|
||||
|
||||
results = definition.limit(@limit).offset(@offset).objects.compact
|
||||
account_ids = results.map(&:id)
|
||||
account_domains = results.map(&:domain).uniq.compact
|
||||
preloaded_relations = relations_map_for_account(@account, account_ids, account_domains)
|
||||
|
||||
results.reject { |target_account| AccountFilter.new(target_account, @account, preloaded_relations).filtered? }
|
||||
rescue Faraday::ConnectionFailed, Parslet::ParseFailed
|
||||
[]
|
||||
end
|
||||
|
||||
def relations_map_for_account(account, account_ids, domains)
|
||||
{
|
||||
blocking: Account.blocking_map(account_ids, account.id),
|
||||
blocked_by: Account.blocked_by_map(account_ids, account.id),
|
||||
muting: Account.muting_map(account_ids, account.id),
|
||||
following: Account.following_map(account_ids, account.id),
|
||||
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, account.id),
|
||||
}
|
||||
end
|
||||
|
||||
def parsed_query
|
||||
SearchQueryTransformer.new.apply(SearchQueryParser.new.parse(@query))
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue