Module: Chewy::Index::Mapping::ClassMethods

Defined in:
lib/chewy/index/mapping.rb

Instance Method Summary collapse

Instance Method Details

#agg(name, &block) ⇒ Object Also known as: aggregation

Defines an aggregation that can be bound to a query or filter

Examples:

# Suppose that a user has posts and each post has ratings
# avg_post_rating is the mean of all ratings
class UsersIndex < Chewy::Index
  index_scope User
  field :posts do
    field :rating
  end

  agg :avg_rating do
    { avg: { field: 'posts.rating' } }
  end
end


147
148
149
# File 'lib/chewy/index/mapping.rb', line 147

def agg(name, &block)
  self._agg_defs = _agg_defs.merge(name => block)
end

#field(*args, **options, &block) ⇒ Object

Defines mapping field for index

The type is optional and defaults to string if not defined:

Also, multiple fields might be defined with one call and with the same options:

The only special option in the field definition is :value. If no :value specified then just corresponding method will be called for the indexed object. Also :value might be a proc or indexed object method name:

The proc evaluates inside the indexed object context if its arity is 0 and in present contexts if there is an argument:

If array was returned as value - it will be put in index as well.

Fields supports nesting in case of object field type. If user.quiz will return an array of objects, then result index content will be an array of hashes, if user.quiz is not a collection association then just values hash will be put in the index.

Nested fields are composed from nested objects:

Of course it is possible to define object fields contents dynamically but make sure evaluation proc returns hash:

The special case is multi_field. If type options and block are both present field is treated as a multi-field. In that case field composition changes satisfy elasticsearch rules:

Examples:

class UsersIndex < Chewy::Index
  index_scope User
  # passing all the options to field definition:
  field :full_name, analyzer: 'special'
end
field :full_name
field :first_name, :last_name, analyzer: 'special'
class User < ActiveRecord::Base
  def user_full_name
    [first_name, last_name].join(' ')
  end
end

field :full_name, type: 'keyword', value: :user_full_name
field :full_name, type: 'keyword', value: -> { [first_name, last_name].join(' ') }

separator = ' '
field :full_name, type: 'keyword', value: ->(user) { [user.first_name, user.last_name].join(separator) }
field :tags, type: 'keyword', value: -> { tags.map(&:name) }
field :quiz do
  field :question, :answer
  field :score, type: 'integer'
end
field :name, value: -> { name_translations } do
  field :ru, value: ->(name) { name['ru'] }
  field :en, value: ->(name) { name['en'] }
end
field :name, type: 'object', value: -> { name_translations }
field :full_name, type: 'text', analyzer: 'name', value: ->{ full_name.try(:strip) } do
  field :sorted, analyzer: 'sorted'
end


124
125
126
127
128
129
130
# File 'lib/chewy/index/mapping.rb', line 124

def field(*args, **options, &block)
  if args.size > 1
    args.map { |name| field(name, **options) }
  else
    expand_nested(Chewy::Fields::Base.new(args.first, **options), &block)
  end
end

#mappings_hashObject

Returns compiled mappings hash for current type



180
181
182
# File 'lib/chewy/index/mapping.rb', line 180

def mappings_hash
  root.mappings_hash
end

#root(**options) ⇒ Object

Defines root object for mapping and is optional for index definition. Use it only if you need to pass options for root object mapping, such as date_detection or dynamic_date_formats

Examples:

class UsersIndex < Chewy::Index
  index_scope User
  # root object defined implicitly and optionless for current type
  field :full_name, type: 'keyword'
end

class CarsIndex < Chewy::Index
  index_scope Car
  # explicit root definition with additional options
  root dynamic_date_formats: ['yyyy-MM-dd'] do
    field :model_name, type: 'keyword'
  end
end


35
36
37
38
39
40
# File 'lib/chewy/index/mapping.rb', line 35

def root(**options)
  self.root_object ||= Chewy::Fields::Root.new(:root, **Chewy.default_root_options.merge(options))
  root_object.update_options!(**options)
  yield if block_given?
  root_object
end

#supports_outdated_sync?true, false

Check whether the type has outdated_sync_field defined with a simple value.

Returns:

  • (true, false)


187
188
189
190
# File 'lib/chewy/index/mapping.rb', line 187

def supports_outdated_sync?
  updated_at_field = root.child_hash[outdated_sync_field] if outdated_sync_field
  !!updated_at_field && updated_at_field.value.nil?
end

#template(*args, **options) ⇒ Object Also known as: dynamic_template

Defines dynamic template in mapping root objects

Name for each template is generated with the following rule: template_#!{dynamic_templates.size + 1}.

Examples:

class CarsIndex < Chewy::Index
  index_scope Car
  template 'model.*', type: 'text', analyzer: 'special'
  field 'model', type: 'object' # here we can put { de: 'Der Mercedes', en: 'Mercedes' }
                                # and template will be applied to this field
end

Templates

template 'tit*', mapping_hash
template 'title.*', mapping_hash # dot in template causes "path_match" using
template /tit.+/, mapping_hash # using "match_pattern": "regexp"
template /title\..+/, mapping_hash # "\." - escaped dot causes "path_match" using
template /tit.+/, type: 'text', mapping_hash # "match_mapping_type" as an optional second argument
template template42: {match: 'hello*', mapping: {type: 'object'}} # or even pass a template as is


173
174
175
# File 'lib/chewy/index/mapping.rb', line 173

def template(*args, **options)
  root.dynamic_template(*args, **options)
end