77 lines
2.4 KiB
Ruby
77 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class E621PoolQueryBuilder
|
|
attr_accessor :params, :must, :must_not, :should, :order
|
|
|
|
def initialize(params)
|
|
@params = params
|
|
@must = []
|
|
@must_not = []
|
|
@should = []
|
|
@order = []
|
|
end
|
|
|
|
def add_tag_string_search(query)
|
|
tag_list = query.split
|
|
aliases = E621::TagAlias.where(antecedent_name: tag_list.map { |t| t.sub(/\A([-~])/, "") })
|
|
tag_list.map do |tag|
|
|
type = :must
|
|
if tag =~ /\A([-~])/
|
|
tag = tag[1..]
|
|
type = $1 == "~" ? :should : :must_not
|
|
end
|
|
if (aliased = aliases.find { |a| a.antecedent_name == tag })
|
|
tag = aliased.consequent_name
|
|
end
|
|
case type
|
|
when :must
|
|
must << { term: { tags: tag } }
|
|
when :must_not
|
|
must_not << { term: { tags: tag } }
|
|
when :should
|
|
should << { term: { tags: tag } }
|
|
end
|
|
end
|
|
end
|
|
|
|
def add_other_search
|
|
must << { match_phrase_prefix: { name: params[:name_matches] } } if params[:name_matches].present?
|
|
must << { match_phrase_prefix: { description: params[:description_matches] } } if params[:description_matches].present?
|
|
must << { term: { creator_id: params[:creator_id] } } if params[:creator_id].present?
|
|
must << { term: { creator_id: Requests::E621.name_to_id(params[:creator_name]) } } if params[:creator_name].present?
|
|
must << { term: { is_active: params[:is_active] } } if params[:is_active].present?
|
|
must << { term: { category: params[:category] } } if params[:category].present?
|
|
must << { term: { id: params[:id] } } if params[:id].present?
|
|
end
|
|
|
|
def add_order
|
|
case params[:order]
|
|
when "name"
|
|
order << { name_kw: :asc }
|
|
when "created_at"
|
|
order << { created_at: :desc }
|
|
when "post_count"
|
|
order << { post_count: :desc }
|
|
when "id_asc"
|
|
order << { id: :asc }
|
|
else
|
|
order << { id: :desc }
|
|
end
|
|
end
|
|
|
|
def search_sql
|
|
q = E621::Pool.all
|
|
q = q.where("string_to_array(tag_string, ' ') @> ARRAY[?]", must) if must.any?
|
|
q = q.where("NOT(string_to_array(tag_string, ' ') && ARRAY[?])", must_not) if must_not.any?
|
|
q = q.where("string_to_array(tag_string, ' ') && ARRAY[?]", should) if should.any?
|
|
q
|
|
end
|
|
|
|
def search(page = 1, limit = 100)
|
|
add_tag_string_search(params[:tags]) if params[:tags].present?
|
|
add_other_search
|
|
add_order
|
|
PoolIndex.search(page, limit, must: must, must_not: must_not, should: should, order: order)
|
|
end
|
|
end
|