Created
October 13, 2014 15:43
-
-
Save namxam/33dca27bdcdb85c58486 to your computer and use it in GitHub Desktop.
Extract all fields from an elastic search model mapping and returns them in a format which can be used in queries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A small elastic search extension to retrieve a list of all field names in a | |
# dot notation. This way we can directly use it in ES queries. | |
# | |
# Example: | |
# | |
# # in app/models/transaction.rb | |
# class Transaction < ActiveRecord::Base | |
# include ElasticSearch::FieldNames | |
# end | |
# | |
module ElasticSearch | |
module FieldNames | |
extend ActiveSupport::Concern | |
class MappingSchema | |
attr_accessor :klass | |
def initialize(klass) | |
self.klass = klass | |
end | |
def to_a | |
schema = only_properties(mapping_fields) | |
flattened_schema = dotify(schema) | |
end | |
def mapping_fields | |
@mapping_fields = klass.mapping.to_hash[klass.document_type.to_sym][:properties] | |
end | |
def dotify(data, key = '') | |
data.each_with_object([]) do |item, result| | |
case item | |
when Hash | |
result << item.map { |k, v| dotify(v, key + k.to_s + '.') } | |
when Array | |
result << item.map { |k| dotify(k, key) } | |
else | |
result << key + item.to_s | |
end | |
end.flatten | |
end | |
def only_properties(hash) | |
hash.map do |key, subhash| | |
if subhash.is_a?(Hash) && subhash.has_key?(:properties) | |
{ key => only_properties(subhash[:properties]) } | |
else | |
key | |
end | |
end | |
end | |
end | |
module ClassMethods | |
def es_field_names | |
@es_field_names ||= MappingSchema.new(self).to_a | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
RSpec.describe ElasticSearch::FieldNames do | |
class MyFieldNamesModel < ActiveRecord::Base | |
include Elasticsearch::Model | |
include ElasticSearch::FieldNames | |
settings do | |
mappings dynamic: 'false' do | |
indexes :name, type: 'string', index: 'not_analyzed' | |
indexes :account do | |
indexes :id, type: 'integer' | |
indexes :name, type: 'string' | |
indexes :owner do | |
indexes :name, type: 'string' | |
end | |
end | |
end | |
end | |
end | |
describe '.es_field_names' do | |
subject { MyFieldNamesModel } | |
it 'returns only strings' do | |
subject.es_field_names.each { |field| expect(field).to be_kind_of(String) } | |
end | |
it 'does not change first level attributes' do | |
expect(subject.es_field_names).to include('name') | |
end | |
it 'prefixes second level elements' do | |
expect(subject.es_field_names).to include('account.id') | |
end | |
it 'prefixes handles multiple second level elements' do | |
expect(subject.es_field_names).to include('account.id', 'account.name') | |
end | |
it 'works for deeply nested elements' do | |
expect(subject.es_field_names).to include('account.owner.name') | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment