Compare commits

..

No commits in common. "388300482cfcb7fce23ad120a5a2ebf89c59a7e0" and "b98a2f01be071fc5c37205d2f6e40913bbe8c2f4" have entirely different histories.

9 changed files with 19 additions and 114 deletions

View file

@ -65,12 +65,7 @@ class StatusesIndex < Chewy::Index
root date_detection: false do
field :id, type: 'long'
field :account_id, type: 'long'
field :created_at, type: 'date'
field :visibility, type: 'keyword'
field :domain, type: 'keyword', value: ->(status) { status.account.domain or Rails.configuration.x.local_domain }
field :lang, type: 'keyword', value: ->(status) { status.language }
field :is, type: 'keyword', value: ->(status) { status.searchable_is }
field :has, type: 'keyword', value: ->(status) { status.searchable_has }
field :text, type: 'text', value: ->(status) { status.searchable_text } do
field :stemmed, type: 'text', analyzer: 'content'

View file

@ -85,7 +85,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
attach_tags(@status)
end
StatusesIndex.import! @status if Chewy.enabled?
StatusesIndex.import! @status
resolve_thread(@status)
fetch_replies(@status)

View file

@ -9,7 +9,7 @@ class SearchQueryParser < Parslet::Parser
rule(:prefix) { (term >> colon).as(:prefix) }
rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) }
rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) }
rule(:clause) { (operator.maybe >> prefix.maybe >> (phrase | term | shortcode)).as(:clause) }
rule(:clause) { (prefix.maybe >> operator.maybe >> (phrase | term | shortcode)).as(:clause) }
rule(:query) { (clause >> space.maybe).repeat.as(:query) }
root(:query)
end

View file

@ -2,7 +2,7 @@
class SearchQueryTransformer < Parslet::Transform
class Query
attr_reader :should_clauses, :must_not_clauses, :must_clauses, :filter_clauses, :order_clauses
attr_reader :should_clauses, :must_not_clauses, :must_clauses, :filter_clauses
def initialize(clauses)
grouped = clauses.chunk(&:operator).to_h
@ -10,20 +10,13 @@ class SearchQueryTransformer < Parslet::Transform
@must_not_clauses = grouped.fetch(:must_not, [])
@must_clauses = grouped.fetch(:must, [])
@filter_clauses = grouped.fetch(:filter, [])
@order_clauses = grouped.fetch(:order, [])
end
def apply(search, account)
def apply(search)
should_clauses.each { |clause| search = search.query.should(clause_to_query(clause)) }
must_clauses.each { |clause| search = search.query.must(clause_to_query(clause)) }
must_not_clauses.each { |clause| search = search.query.must_not(clause_to_query(clause)) }
filter_clauses.each { |clause| search = search.filter(**clause_to_filter(clause, account)) }
if order_clauses.empty?
# Default to most recent results first.
search = search.order(created_at: :desc)
else
order_clauses.each { |clause| search = search.order(**clause_to_order(clause)) }
end
filter_clauses.each { |clause| search = search.filter(**clause_to_filter(clause)) }
search.query.minimum_should_match(1)
end
@ -35,30 +28,19 @@ class SearchQueryTransformer < Parslet::Transform
{ multi_match: { type: 'most_fields', query: clause.term, fields: ['text', 'text.stemmed'] } }
when PhraseClause
{ match_phrase: { text: { query: clause.phrase } } }
else
raise "Unexpected clause type: #{clause}"
end
end
def clause_to_filter(clause)
case clause
when PrefixClause
{ term: { clause.filter => clause.term } }
else
raise "Unexpected clause type: #{clause}"
end
end
def clause_to_filter(clause, account)
case clause
when PrefixClause
{ clause.query => { clause.filter => clause.term == :account_id_placeholder ? account.id : clause.term } }
else
raise "Unexpected clause type: #{clause}"
end
end
def clause_to_order(clause)
case clause
when PrefixClause
{ clause.term => clause.order }
else
raise "Unexpected clause type: #{clause}"
end
end
end
class Operator
@ -99,35 +81,11 @@ class SearchQueryTransformer < Parslet::Transform
end
class PrefixClause
attr_reader :filter, :operator, :term, :order, :query
def initialize(prefix, operator, term)
@query = :term
case operator
when '+', nil
@operator = :filter
when '-'
@operator = :must_not
else
raise "Unknown operator: #{str}"
end
attr_reader :filter, :operator, :term
def initialize(prefix, term)
@operator = :filter
case prefix
when 'domain', 'is', 'has', 'lang', 'visibility'
@filter = prefix.to_s
@term = term
when 'before', 'after'
@query = :range
@filter = 'created_at'
case prefix
when 'before'
@term = { lt: term }
when 'after'
@term = { gt: term }
else
raise Mastodon::SyntaxError
end
when 'from'
@filter = :account_id
@ -136,25 +94,6 @@ class SearchQueryTransformer < Parslet::Transform
account = Account.find_remote!(username, domain)
@term = account.id
when 'scope'
raise Mastodon::SyntaxError unless operator.nil?
raise Mastodon::SyntaxError unless term == 'classic'
@filter = 'searchable_by'
@term = :account_id_placeholder
when 'sort'
raise Mastodon::SyntaxError unless operator.nil?
@operator = :order
@term = :created_at
case term
when 'oldest'
@order = :asc
when 'newest'
@order = :desc
else
raise Mastodon::SyntaxError
end
else
raise Mastodon::SyntaxError
end
@ -166,7 +105,7 @@ class SearchQueryTransformer < Parslet::Transform
operator = clause[:operator]&.to_s
if clause[:prefix]
PrefixClause.new(prefix, operator, clause[:term].to_s)
PrefixClause.new(prefix, clause[:term].to_s)
elsif clause[:term]
TermClause.new(prefix, operator, clause[:term].to_s)
elsif clause[:shortcode]

View file

@ -189,27 +189,6 @@ class Status < ApplicationRecord
].compact.join("\n\n")
end
def searchable_is
keywords = []
keywords << :bot if account.bot?
keywords << :local if local?
keywords << :local_only if local_only
keywords << :reply if reply?
keywords << :sensitive if sensitive?
keywords
end
def searchable_has
keywords = []
keywords << :cw if spoiler_text?
keywords << :link if FetchLinkCardService.new.link?(self)
keywords << :media if media_attachments.present?
keywords << :mention if mentions.present?
keywords << :poll if preloadable_poll.present?
keywords << :tag if tags.present?
keywords
end
def to_log_human_identifier
account.acct
end

View file

@ -91,7 +91,7 @@ class ActivityPub::ProcessAccountService < BaseService
@account.save_with_optional_media!
AccountsIndex.import! @account if Chewy.enabled?
AccountsIndex.import! @account
end
def set_immediate_protocol_attributes!

View file

@ -54,7 +54,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
broadcast_updates!
end
StatusesIndex.import! @status if Chewy.enabled?
StatusesIndex.import! @status
forward_activity! if significant_changes? && @status_parser.edited_at > last_edit_date
end

View file

@ -34,14 +34,6 @@ class FetchLinkCardService < BaseService
nil
end
##
# Borrow most of this machinery to detect whether the status has at least one link.
def link?(status)
@status = status
@original_url = parse_urls
!@original_url.nil?
end
private
def process_url

View file

@ -42,7 +42,7 @@ class SearchService < BaseService
when :public_or_unlisted
statuses_index = statuses_index.filter.or(terms: { visibility: ['public', 'unlisted'] })
end
definition = parsed_query.apply(statuses_index, @account)
definition = parsed_query.apply(statuses_index)
if @options[:account_id].present?
definition = definition.filter(term: { account_id: @options[:account_id] })