cirandas.net

ref: master

plugins/elasticsearch/lib/searchable_model/elasticsearch_indexed_model.rb


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
require_relative '../nested_helper/environment'

module ElasticsearchIndexedModel

  def self.included base
    base.send :include, Elasticsearch::Model
    base.send :include, Elasticsearch::Model::Callbacks

    base.send :index_name, "#{Rails.env}_#{base.index_name}"

    base.extend ClassMethods
    base.send :include, InstanceMethods

    base.class_eval do
      settings index: { number_of_shards: 1 } do
        mappings dynamic: 'false' do
          base.indexed_fields.each do |field, value|
            type = value[:type].presence
            type = :string if type == :text

            if type == :nested
              indexes(field, type: type) do
                value[:hash].each do |hash_field, hash_value|
                  indexes(hash_field, base.indexes_as_hash(hash_field,hash_value[:type].presence))
                end
              end
            else
               indexes(field, base.indexes_as_hash(field,type))
            end
            print '.'
          end
        end

        base.__elasticsearch__.client.indices.delete \
          index: base.index_name rescue nil
        base.__elasticsearch__.client.indices.create \
          index: base.index_name,
          body: {
            settings: base.settings.to_hash,
            mappings: base.mappings.to_hash
          }
      end
    end
   base.send :import
  end

  module ClassMethods

    def indexes_as_hash(name, type)
      hash = {}
      if type.nil?
        hash[:fields] = raw_field(name, type)
      else
        hash[:type] = type if not type.nil?
      end
      hash
    end

    def raw_field name, type
      {
        raw: {
          type: "string",
          index: "not_analyzed"
        }
      }
    end

    def indexed_fields
      fields = {
                :environment  => {type: :nested, hash: NestedEnvironment::hash },
                :category_ids => {type: :integer },
                :created_at   => {type: :date }
      }
      fields.update(self::SEARCHABLE_FIELDS)
      fields.update(self.control_fields)
      fields
    end

  end

  module InstanceMethods
    def as_indexed_json options={}
        attrs = {}

        self.class.indexed_fields.each do |field, value|
          type = value[:type].presence
          if type == :nested
            attrs[field] = {}
            value[:hash].each do |hash_field, hash_value|
              attrs[field][hash_field] = self.send(field).send(hash_field)
            end
          else
            attrs[field] = self.send(field)
          end
        end
        attrs.as_json
    end
  end

end