module Chewy::Index::Mapping::ClassMethods
Public Instance Methods
Defines an aggregation that can be bound to a query or filter
@example
# 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
# File lib/chewy/index/mapping.rb, line 147 def agg(name, &block) self._agg_defs = _agg_defs.merge(name => block) end
Defines mapping field for index
@example
class UsersIndex < Chewy::Index index_scope User # passing all the options to field definition: field :full_name, analyzer: 'special' end
The ‘type` is optional and defaults to `string` if not defined:
@example
field :full_name
Also, multiple fields might be defined with one call and with the same options:
@example
field :first_name, :last_name, analyzer: 'special'
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:
@example
class User < ActiveRecord::Base def user_full_name [first_name, last_name].join(' ') end end field :full_name, type: 'keyword', value: :user_full_name
The proc evaluates inside the indexed object context if its arity is 0 and in present contexts if there is an argument:
@example
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) }
If array was returned as value - it will be put in index as well.
@example
field :tags, type: 'keyword', value: -> { tags.map(&:name) }
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.
@example
field :quiz do field :question, :answer field :score, type: 'integer' end
Nested fields are composed from nested objects:
@example
field :name, value: -> { name_translations } do field :ru, value: ->(name) { name['ru'] } field :en, value: ->(name) { name['en'] } end
Of course it is possible to define object fields contents dynamically but make sure evaluation proc returns hash:
@example
field :name, type: 'object', value: -> { name_translations }
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:
@example
field :full_name, type: 'text', analyzer: 'name', value: ->{ full_name.try(:strip) } do field :sorted, analyzer: 'sorted' end
# 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
Returns compiled mappings hash for current type
# File lib/chewy/index/mapping.rb, line 180 def mappings_hash root.mappings_hash end
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`
@example
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
# 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
Check whether the type has outdated_sync_field defined with a simple value.
@return [true, false]
# 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
Defines dynamic template in mapping root objects
@example
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
Name for each template is generated with the following rule: ‘template_#!{dynamic_templates.size + 1}`.
@example 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
# File lib/chewy/index/mapping.rb, line 173 def template(*args, **options) root.dynamic_template(*args, **options) end
Private Instance Methods
# File lib/chewy/index/mapping.rb, line 194 def expand_nested(field) @_current_field ||= root if @_current_field field.parent = @_current_field @_current_field.children.push(field) end return unless block_given? previous_field = @_current_field @_current_field = field yield @_current_field = previous_field end