From d601d54ceaaf1c3107d22c0c3c7eb5d8149781c3 Mon Sep 17 00:00:00 2001 From: Macartur Sousa Date: Thu, 7 Jul 2016 17:28:56 -0300 Subject: [PATCH] Elasticsearch: Adding filter --- plugins/elasticsearch/helpers/elasticsearch_helper.rb | 43 +++++++++++++++++++++++++++---------------- plugins/elasticsearch/lib/elasticsearch_indexed_model.rb | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- plugins/elasticsearch/lib/ext/community.rb | 15 ++++++++++++++- plugins/elasticsearch/lib/ext/person.rb | 4 ++-- plugins/elasticsearch/lib/ext/text_article.rb | 17 ++++++++++++++--- plugins/elasticsearch/lib/nested_environment.rb | 8 ++++++++ 6 files changed, 144 insertions(+), 29 deletions(-) create mode 100644 plugins/elasticsearch/lib/nested_environment.rb diff --git a/plugins/elasticsearch/helpers/elasticsearch_helper.rb b/plugins/elasticsearch/helpers/elasticsearch_helper.rb index 0279681..5450bfa 100644 --- a/plugins/elasticsearch/helpers/elasticsearch_helper.rb +++ b/plugins/elasticsearch/helpers/elasticsearch_helper.rb @@ -63,31 +63,42 @@ module ElasticsearchHelper end end - def query_method expression="", fields=[] - query_exp = {} - if expression.blank? - else - query_exp = { - query: { - query_string: { - query: "*"+expression.downcase.split.join('* *')+"*", - fields: fields, - tie_breaker: 0.4, - minimum_should_match: "100%" - }, + def query_string expression="", models=[] + return { match_all: {} } if not expression + + { + query_string: { + query: "*"+expression.downcase.split.join('* *')+"*", + fields: fields_from_models(models), + tie_breaker: 0.4, + minimum_should_match: "100%" + } + } + end + + + def query_method expression="", models=[] + { + query: { + filtered: { + query: query_string(expression,models), + filter: { + bool: { + should: models.map {|model| model.filter(environment: @environment.id)} + } + } } } - end - query_exp + } end def get_query text="", options={} klass = options[:klass] sort_by = options[:sort_by] - fields = klass.nil? ? (fields_from_models searchable_models) : (fields_from_models [klass]) + models = (klass.nil?) ? searchable_models : [klass] - query = query_method(text, fields) + query = query_method(text, models) query[:sort] = sort_by if sort_by query end diff --git a/plugins/elasticsearch/lib/elasticsearch_indexed_model.rb b/plugins/elasticsearch/lib/elasticsearch_indexed_model.rb index 9051555..aa774f4 100644 --- a/plugins/elasticsearch/lib/elasticsearch_indexed_model.rb +++ b/plugins/elasticsearch/lib/elasticsearch_indexed_model.rb @@ -1,3 +1,5 @@ +require_relative 'nested_environment' + module ElasticsearchIndexedModel def self.included base @@ -5,17 +7,24 @@ module ElasticsearchIndexedModel 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| - value = {} if value.nil? - type = value[:type].presence - if type.nil? - indexes(field, fields: base.raw_field(field)) + type = value[:type].presence + + 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, type: type + indexes(field, base.indexes_as_hash(field,type)) end print '.' end @@ -35,7 +44,18 @@ module ElasticsearchIndexedModel end module ClassMethods - def raw_field name + + 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", @@ -45,9 +65,61 @@ module ElasticsearchIndexedModel end def indexed_fields - self::SEARCHABLE_FIELDS.merge self.control_fields + fields = { + :environment => {type: :nested, hash: NestedEnvironment.environment_hash }, + :created_at => {type: :date } + } + fields.update(self::SEARCHABLE_FIELDS) + fields.update(self.control_fields) + fields + end + + def environment_filter environment=1 + { + query: { + nested: { + path: "environment", + query: { + bool: { + must: { term: { "environment.id" => environment } }, + } + } + } + } + } end + def filter options={} + environment = options[:environment].presence + + filter = {} + filter[:indices] = {:index => self.index_name, :no_match_filter => "none" } + filter[:indices][:filter] = { :bool => {} } + filter[:indices][:filter][:bool][:must] = [ environment_filter(environment) ] + filter[:indices][:filter][:bool][:should] = [ { :and => self.should_and } ] if self.respond_to? :should_and + filter + 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 diff --git a/plugins/elasticsearch/lib/ext/community.rb b/plugins/elasticsearch/lib/ext/community.rb index b64d1bf..7079efb 100644 --- a/plugins/elasticsearch/lib/ext/community.rb +++ b/plugins/elasticsearch/lib/ext/community.rb @@ -2,10 +2,23 @@ require_dependency 'community' require_relative '../elasticsearch_indexed_model' class Community + def self.control_fields { - :created_at => {type: 'date'} + :secret => { type: :boolean }, + :visible => { type: :boolean }, } end + + # community visible + def self.should_and + [ + {term: { :secret => false }}, + {term: { :visible => true }} + ] + end + + include ElasticsearchIndexedModel + end diff --git a/plugins/elasticsearch/lib/ext/person.rb b/plugins/elasticsearch/lib/ext/person.rb index 3348442..1ce563d 100644 --- a/plugins/elasticsearch/lib/ext/person.rb +++ b/plugins/elasticsearch/lib/ext/person.rb @@ -4,9 +4,9 @@ require_relative '../elasticsearch_indexed_model' class Person def self.control_fields { - :visible => {type: 'boolean'}, + :visible => {type: 'boolean'}, :public_profile => {type: 'boolean'}, - :created_at => {type: 'date'} + :created_at => {type: 'date'} } end include ElasticsearchIndexedModel diff --git a/plugins/elasticsearch/lib/ext/text_article.rb b/plugins/elasticsearch/lib/ext/text_article.rb index 7185aee..4eda103 100644 --- a/plugins/elasticsearch/lib/ext/text_article.rb +++ b/plugins/elasticsearch/lib/ext/text_article.rb @@ -6,12 +6,23 @@ require_dependency 'text_article' require_relative '../elasticsearch_indexed_model' class TextArticle + + def self.profile_hash + { + :id => { type: :integer }, + :visible => { type: :boolean }, + :public_profile => { type: :boolean } + } + end + + def self.control_fields { - :advertise => {}, - :published => {}, - :created_at => {type: 'date'} + :advertise => { type: :boolean }, + :published => { type: 'boolean'}, + :profile => { type: :nested , hash: self.profile_hash } } end + include ElasticsearchIndexedModel end diff --git a/plugins/elasticsearch/lib/nested_environment.rb b/plugins/elasticsearch/lib/nested_environment.rb new file mode 100644 index 0000000..7f5fb64 --- /dev/null +++ b/plugins/elasticsearch/lib/nested_environment.rb @@ -0,0 +1,8 @@ +module NestedEnvironment + def self.environment_hash + { + :id => { type: :integer }, + :is_default => {type: :boolean } + } + end +end -- libgit2 0.21.2