Sha256: f5f1b2d6d4bb6a6a2b597db392f7889454287d3a80a827c709c243d45598e808

Contents?: true

Size: 1.56 KB

Versions: 2

Compression:

Stored size: 1.56 KB

Contents

require "elasticsearch"
require "json"

require_relative "search/index"

module Tagliani
  class Search
    class << self
      def client
        Elasticsearch::Client.new host: Tagliani.config.elasticsearch.url,
                                  log: Tagliani.config.elasticsearch.log
      end
    end

    attr_reader :client

    def initialize(body:, where: nil)
      @index = Tagliani.config.elasticsearch.index
      @client = self.class.client
      @where_clause = where
      @body = body

      build_where(@where_clause) if @where_clause
    end

    def response
      @client.search(index: @index, body: @body)
    end

    def serialize(type:)
      model_kls = "#{type}_kls"
      model_id = "#{type}_id"

      models = {}

      response['hits']['hits'].each do |entry|
        entry_source = entry['_source']
        class_name = entry_source[model_kls]
        models[class_name] ||= []
        models[class_name] << entry_source[model_id]
      end

      models.flat_map do |model, ids|
        model.constantize.where(id: ids)
      end
    end

    private

    def build_where(args)
      @body[:query] ||= {}
      @body[:query][:bool] ||= {}
      @body[:query][:bool][:must] ||= []
      
      @body[:query][:bool][:must] << [
        query_string: {
          query: build_query_string(args)
        }
      ]
    end

    def build_query_string(args)
      query = args.to_h.map do |key, val|
        "(#{val.map { |object| "#{key}:#{object}" }.join(' OR ')})"
      end.join(' AND ')
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
tagliani-0.1.1 lib/tagliani/search.rb
tagliani-0.1.0 lib/tagliani/search.rb