# 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