Commit 7a9a3db4a91c227a8d3c53547bbf9e3d300a860f
1 parent
d601d54c
Exists in
staging
and in
6 other branches
Elasticsearch: Altering filter structure
Adding nested query: * NestedEnvironment * NestedProfile Adding bool query: * should * must * must_not Moved elasticsearch_indexed_model to helpers folder Signed-off-by: Macartur Sousa <macartur.sc@gmail.com>
Showing
13 changed files
with
304 additions
and
171 deletions
Show diff stats
plugins/elasticsearch/helpers/elasticsearch_helper.rb
| @@ -84,7 +84,7 @@ module ElasticsearchHelper | @@ -84,7 +84,7 @@ module ElasticsearchHelper | ||
| 84 | query: query_string(expression,models), | 84 | query: query_string(expression,models), |
| 85 | filter: { | 85 | filter: { |
| 86 | bool: { | 86 | bool: { |
| 87 | - should: models.map {|model| model.filter(environment: @environment.id)} | 87 | + should: models.map {|model| model.filter(environment: @environment.id) } |
| 88 | } | 88 | } |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
plugins/elasticsearch/helpers/nested_helper/environment.rb
0 → 100644
| @@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
| 1 | +module NestedEnvironment | ||
| 2 | + | ||
| 3 | + def self.environment_hash | ||
| 4 | + { | ||
| 5 | + :id => { type: :integer }, | ||
| 6 | + :is_default => {type: :boolean } | ||
| 7 | + } | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def self.environment_filter environment=1 | ||
| 11 | + { | ||
| 12 | + query: { | ||
| 13 | + nested: { | ||
| 14 | + path: "environment", | ||
| 15 | + query: { | ||
| 16 | + bool: { | ||
| 17 | + must: { term: { "environment.id" => environment } }, | ||
| 18 | + } | ||
| 19 | + } | ||
| 20 | + } | ||
| 21 | + } | ||
| 22 | + } | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | +end |
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +module NestedProfile | ||
| 2 | + | ||
| 3 | + def self.hash | ||
| 4 | + { | ||
| 5 | + :id => { type: :integer }, | ||
| 6 | + :visible => { type: :boolean }, | ||
| 7 | + :public_profile => { type: :boolean } | ||
| 8 | + } | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def self.filter | ||
| 12 | + { | ||
| 13 | + query: { | ||
| 14 | + nested: { | ||
| 15 | + path: "profile", | ||
| 16 | + query: { | ||
| 17 | + bool: { | ||
| 18 | + must:[ | ||
| 19 | + { term: { "profile.visible" => true } }, | ||
| 20 | + { term: { "profile.public_profile" => true } } | ||
| 21 | + ], | ||
| 22 | + } | ||
| 23 | + } | ||
| 24 | + } | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | +end |
plugins/elasticsearch/helpers/searchable_model/elasticsearch_indexed_model.rb
0 → 100644
| @@ -0,0 +1,99 @@ | @@ -0,0 +1,99 @@ | ||
| 1 | +require_relative '../nested_helper/environment' | ||
| 2 | + | ||
| 3 | +module ElasticsearchIndexedModel | ||
| 4 | + | ||
| 5 | + def self.included base | ||
| 6 | + base.send :include, Elasticsearch::Model | ||
| 7 | + base.send :include, Elasticsearch::Model::Callbacks | ||
| 8 | + | ||
| 9 | + base.send :index_name, "#{Rails.env}_#{base.index_name}" | ||
| 10 | + | ||
| 11 | + base.extend ClassMethods | ||
| 12 | + base.send :include, InstanceMethods | ||
| 13 | + | ||
| 14 | + base.class_eval do | ||
| 15 | + settings index: { number_of_shards: 1 } do | ||
| 16 | + mappings dynamic: 'false' do | ||
| 17 | + base.indexed_fields.each do |field, value| | ||
| 18 | + type = value[:type].presence | ||
| 19 | + | ||
| 20 | + if type == :nested | ||
| 21 | + indexes(field, type: type) do | ||
| 22 | + value[:hash].each do |hash_field, hash_value| | ||
| 23 | + indexes(hash_field, base.indexes_as_hash(hash_field,hash_value[:type].presence)) | ||
| 24 | + end | ||
| 25 | + end | ||
| 26 | + else | ||
| 27 | + indexes(field, base.indexes_as_hash(field,type)) | ||
| 28 | + end | ||
| 29 | + print '.' | ||
| 30 | + end | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + base.__elasticsearch__.client.indices.delete \ | ||
| 34 | + index: base.index_name rescue nil | ||
| 35 | + base.__elasticsearch__.client.indices.create \ | ||
| 36 | + index: base.index_name, | ||
| 37 | + body: { | ||
| 38 | + settings: base.settings.to_hash, | ||
| 39 | + mappings: base.mappings.to_hash | ||
| 40 | + } | ||
| 41 | + end | ||
| 42 | + end | ||
| 43 | + base.send :import | ||
| 44 | + end | ||
| 45 | + | ||
| 46 | + module ClassMethods | ||
| 47 | + | ||
| 48 | + def indexes_as_hash(name, type) | ||
| 49 | + hash = {} | ||
| 50 | + if type.nil? | ||
| 51 | + hash[:fields] = raw_field(name, type) | ||
| 52 | + else | ||
| 53 | + hash[:type] = type if not type.nil? | ||
| 54 | + end | ||
| 55 | + hash | ||
| 56 | + end | ||
| 57 | + | ||
| 58 | + def raw_field name, type | ||
| 59 | + { | ||
| 60 | + raw: { | ||
| 61 | + type: "string", | ||
| 62 | + index: "not_analyzed" | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + end | ||
| 66 | + | ||
| 67 | + def indexed_fields | ||
| 68 | + fields = { | ||
| 69 | + :environment => {type: :nested, hash: NestedEnvironment::environment_hash }, | ||
| 70 | + :created_at => {type: :date } | ||
| 71 | + } | ||
| 72 | + fields.update(self::SEARCHABLE_FIELDS) | ||
| 73 | + fields.update(self.control_fields) | ||
| 74 | + fields | ||
| 75 | + end | ||
| 76 | + | ||
| 77 | + end | ||
| 78 | + | ||
| 79 | + module InstanceMethods | ||
| 80 | + def as_indexed_json options={} | ||
| 81 | + attrs = {} | ||
| 82 | + | ||
| 83 | + self.class.indexed_fields.each do |field, value| | ||
| 84 | + type = value[:type].presence | ||
| 85 | + | ||
| 86 | + if type == :nested | ||
| 87 | + attrs[field] = {} | ||
| 88 | + value[:hash].each do |hash_field, hash_value| | ||
| 89 | + attrs[field][hash_field] = self.send(field).send(hash_field) | ||
| 90 | + end | ||
| 91 | + else | ||
| 92 | + attrs[field] = self.send(field) | ||
| 93 | + end | ||
| 94 | + end | ||
| 95 | + attrs.as_json | ||
| 96 | + end | ||
| 97 | + end | ||
| 98 | + | ||
| 99 | +end |
plugins/elasticsearch/helpers/searchable_model/filter.rb
0 → 100644
| @@ -0,0 +1,43 @@ | @@ -0,0 +1,43 @@ | ||
| 1 | +require_relative '../nested_helper/environment' | ||
| 2 | + | ||
| 3 | +module Filter | ||
| 4 | + | ||
| 5 | + def self.included base | ||
| 6 | + base.extend ClassMethods | ||
| 7 | + base.send :include, InstanceMethods | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + module ClassMethods | ||
| 11 | + | ||
| 12 | + def filter options={} | ||
| 13 | + environment = options[:environment].presence | ||
| 14 | + | ||
| 15 | + result_filter = {} | ||
| 16 | + result_filter[:indices] = {:index => self.index_name, :no_match_filter => "none" } | ||
| 17 | + result_filter[:indices][:filter] = { :bool => self.filter_bool(environment) } | ||
| 18 | + | ||
| 19 | + result_filter | ||
| 20 | + end | ||
| 21 | + | ||
| 22 | + def filter_bool environment | ||
| 23 | + result_filter = {} | ||
| 24 | + | ||
| 25 | + result_filter[:must] = [ NestedEnvironment::environment_filter(environment) ] | ||
| 26 | + | ||
| 27 | + self.nested_filter.each {|filter| result_filter[:must].append(filter)} if self.respond_to? :nested_filter | ||
| 28 | + self.must.each {|filter| result_filter[:must].append(filter) } if self.respond_to? :must | ||
| 29 | + | ||
| 30 | + result_filter[:should] = self.should if self.respond_to? :should | ||
| 31 | + result_filter[:must_not] = self.must_not if self.respond_to? :must_not | ||
| 32 | + | ||
| 33 | + result_filter | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + end | ||
| 38 | + | ||
| 39 | + module InstanceMethods | ||
| 40 | + | ||
| 41 | + end | ||
| 42 | + | ||
| 43 | +end |
plugins/elasticsearch/helpers/searchable_model_helper.rb
0 → 100644
| @@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
| 1 | +require_relative './searchable_model/elasticsearch_indexed_model' | ||
| 2 | +require_relative './searchable_model/filter' | ||
| 3 | + | ||
| 4 | +module SearchableModelHelper | ||
| 5 | + def self.included base | ||
| 6 | + base.send :include, ElasticsearchIndexedModel | ||
| 7 | + base.send :include, Filter | ||
| 8 | + end | ||
| 9 | +end |
plugins/elasticsearch/lib/elasticsearch_indexed_model.rb
| @@ -1,125 +0,0 @@ | @@ -1,125 +0,0 @@ | ||
| 1 | -require_relative 'nested_environment' | ||
| 2 | - | ||
| 3 | -module ElasticsearchIndexedModel | ||
| 4 | - | ||
| 5 | - def self.included base | ||
| 6 | - base.send :include, Elasticsearch::Model | ||
| 7 | - base.send :include, Elasticsearch::Model::Callbacks | ||
| 8 | - | ||
| 9 | - base.send :index_name, "#{Rails.env}_#{base.index_name}" | ||
| 10 | - | ||
| 11 | - base.extend ClassMethods | ||
| 12 | - base.send :include, InstanceMethods | ||
| 13 | - | ||
| 14 | - base.class_eval do | ||
| 15 | - settings index: { number_of_shards: 1 } do | ||
| 16 | - mappings dynamic: 'false' do | ||
| 17 | - base.indexed_fields.each do |field, value| | ||
| 18 | - type = value[:type].presence | ||
| 19 | - | ||
| 20 | - if type == :nested | ||
| 21 | - indexes(field, type: type) do | ||
| 22 | - value[:hash].each do |hash_field, hash_value| | ||
| 23 | - indexes(hash_field, base.indexes_as_hash(hash_field,hash_value[:type].presence)) | ||
| 24 | - end | ||
| 25 | - end | ||
| 26 | - else | ||
| 27 | - indexes(field, base.indexes_as_hash(field,type)) | ||
| 28 | - end | ||
| 29 | - print '.' | ||
| 30 | - end | ||
| 31 | - end | ||
| 32 | - | ||
| 33 | - base.__elasticsearch__.client.indices.delete \ | ||
| 34 | - index: base.index_name rescue nil | ||
| 35 | - base.__elasticsearch__.client.indices.create \ | ||
| 36 | - index: base.index_name, | ||
| 37 | - body: { | ||
| 38 | - settings: base.settings.to_hash, | ||
| 39 | - mappings: base.mappings.to_hash | ||
| 40 | - } | ||
| 41 | - end | ||
| 42 | - end | ||
| 43 | - base.send :import | ||
| 44 | - end | ||
| 45 | - | ||
| 46 | - module ClassMethods | ||
| 47 | - | ||
| 48 | - def indexes_as_hash(name, type) | ||
| 49 | - hash = {} | ||
| 50 | - if type.nil? | ||
| 51 | - hash[:fields] = raw_field(name, type) | ||
| 52 | - else | ||
| 53 | - hash[:type] = type if not type.nil? | ||
| 54 | - end | ||
| 55 | - hash | ||
| 56 | - end | ||
| 57 | - | ||
| 58 | - def raw_field name, type | ||
| 59 | - { | ||
| 60 | - raw: { | ||
| 61 | - type: "string", | ||
| 62 | - index: "not_analyzed" | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - end | ||
| 66 | - | ||
| 67 | - def indexed_fields | ||
| 68 | - fields = { | ||
| 69 | - :environment => {type: :nested, hash: NestedEnvironment.environment_hash }, | ||
| 70 | - :created_at => {type: :date } | ||
| 71 | - } | ||
| 72 | - fields.update(self::SEARCHABLE_FIELDS) | ||
| 73 | - fields.update(self.control_fields) | ||
| 74 | - fields | ||
| 75 | - end | ||
| 76 | - | ||
| 77 | - def environment_filter environment=1 | ||
| 78 | - { | ||
| 79 | - query: { | ||
| 80 | - nested: { | ||
| 81 | - path: "environment", | ||
| 82 | - query: { | ||
| 83 | - bool: { | ||
| 84 | - must: { term: { "environment.id" => environment } }, | ||
| 85 | - } | ||
| 86 | - } | ||
| 87 | - } | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - end | ||
| 91 | - | ||
| 92 | - def filter options={} | ||
| 93 | - environment = options[:environment].presence | ||
| 94 | - | ||
| 95 | - filter = {} | ||
| 96 | - filter[:indices] = {:index => self.index_name, :no_match_filter => "none" } | ||
| 97 | - filter[:indices][:filter] = { :bool => {} } | ||
| 98 | - filter[:indices][:filter][:bool][:must] = [ environment_filter(environment) ] | ||
| 99 | - filter[:indices][:filter][:bool][:should] = [ { :and => self.should_and } ] if self.respond_to? :should_and | ||
| 100 | - filter | ||
| 101 | - end | ||
| 102 | - | ||
| 103 | - end | ||
| 104 | - | ||
| 105 | - module InstanceMethods | ||
| 106 | - def as_indexed_json options={} | ||
| 107 | - attrs = {} | ||
| 108 | - | ||
| 109 | - self.class.indexed_fields.each do |field, value| | ||
| 110 | - type = value[:type].presence | ||
| 111 | - | ||
| 112 | - if type == :nested | ||
| 113 | - attrs[field] = {} | ||
| 114 | - value[:hash].each do |hash_field, hash_value| | ||
| 115 | - attrs[field][hash_field] = self.send(field).send(hash_field) | ||
| 116 | - end | ||
| 117 | - else | ||
| 118 | - attrs[field] = self.send(field) | ||
| 119 | - end | ||
| 120 | - end | ||
| 121 | - attrs.as_json | ||
| 122 | - end | ||
| 123 | - end | ||
| 124 | - | ||
| 125 | -end |
plugins/elasticsearch/lib/ext/community.rb
| 1 | require_dependency 'community' | 1 | require_dependency 'community' |
| 2 | -require_relative '../elasticsearch_indexed_model' | 2 | +require_relative '../../helpers/searchable_model_helper' |
| 3 | 3 | ||
| 4 | class Community | 4 | class Community |
| 5 | 5 | ||
| 6 | def self.control_fields | 6 | def self.control_fields |
| 7 | { | 7 | { |
| 8 | - :secret => { type: :boolean }, | ||
| 9 | - :visible => { type: :boolean }, | 8 | + :secret => { type: :boolean }, |
| 9 | + :visible => { type: :boolean }, | ||
| 10 | } | 10 | } |
| 11 | end | 11 | end |
| 12 | 12 | ||
| 13 | - # community visible | ||
| 14 | - def self.should_and | 13 | + def self.should |
| 15 | [ | 14 | [ |
| 16 | - {term: { :secret => false }}, | ||
| 17 | - {term: { :visible => true }} | 15 | + { and: |
| 16 | + [ | ||
| 17 | + {term: { :secret => false }}, | ||
| 18 | + {term: { :visible => true }} | ||
| 19 | + ] | ||
| 20 | + } | ||
| 18 | ] | 21 | ] |
| 19 | end | 22 | end |
| 20 | 23 | ||
| 21 | - | ||
| 22 | - include ElasticsearchIndexedModel | ||
| 23 | - | 24 | + include SearchableModelHelper |
| 24 | end | 25 | end |
plugins/elasticsearch/lib/ext/event.rb
| 1 | require_dependency 'event' | 1 | require_dependency 'event' |
| 2 | -require_relative '../elasticsearch_indexed_model' | 2 | + |
| 3 | +require_relative '../../helpers/searchable_model_helper' | ||
| 4 | +require_relative '../../helpers/nested_helper/profile' | ||
| 3 | 5 | ||
| 4 | class Event | 6 | class Event |
| 7 | + | ||
| 5 | def self.control_fields | 8 | def self.control_fields |
| 6 | { | 9 | { |
| 7 | - :advertise => {}, | ||
| 8 | - :published => {}, | ||
| 9 | - :created_at => {type: 'date'} | 10 | + :advertise => {type: :boolean}, |
| 11 | + :published => {type: :boolean}, | ||
| 12 | + :profile => { type: :nested , hash: NestedProfile.hash } | ||
| 10 | } | 13 | } |
| 11 | end | 14 | end |
| 12 | - include ElasticsearchIndexedModel | 15 | + |
| 16 | + def self.should | ||
| 17 | + [ | ||
| 18 | + { and: [ | ||
| 19 | + { term: { advertise: true }}, | ||
| 20 | + { term: { published: true }} | ||
| 21 | + ] | ||
| 22 | + } | ||
| 23 | + ] | ||
| 24 | + end | ||
| 25 | + | ||
| 26 | + def self.nested_filter | ||
| 27 | + [ | ||
| 28 | + NestedProfile::filter | ||
| 29 | + ] | ||
| 30 | + end | ||
| 31 | + | ||
| 32 | + include SearchableModelHelper | ||
| 13 | end | 33 | end |
plugins/elasticsearch/lib/ext/person.rb
| 1 | require_dependency 'person' | 1 | require_dependency 'person' |
| 2 | -require_relative '../elasticsearch_indexed_model' | 2 | + |
| 3 | +require_relative '../../helpers/searchable_model_helper' | ||
| 3 | 4 | ||
| 4 | class Person | 5 | class Person |
| 6 | + | ||
| 5 | def self.control_fields | 7 | def self.control_fields |
| 6 | { | 8 | { |
| 7 | :visible => {type: 'boolean'}, | 9 | :visible => {type: 'boolean'}, |
| 8 | - :public_profile => {type: 'boolean'}, | ||
| 9 | - :created_at => {type: 'date'} | 10 | + :secret => { type: :boolean }, |
| 10 | } | 11 | } |
| 11 | end | 12 | end |
| 12 | - include ElasticsearchIndexedModel | 13 | + |
| 14 | + def self.should | ||
| 15 | + [ | ||
| 16 | + { and: | ||
| 17 | + [ | ||
| 18 | + {term: { :secret => false }}, | ||
| 19 | + {term: { :visible => true }} | ||
| 20 | + ] | ||
| 21 | + } | ||
| 22 | + ] | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + include SearchableModelHelper | ||
| 13 | end | 26 | end |
plugins/elasticsearch/lib/ext/text_article.rb
| 1 | # REQUIRE TO LOAD DESCENDANTS FROM TEXT_ARTICLE | 1 | # REQUIRE TO LOAD DESCENDANTS FROM TEXT_ARTICLE |
| 2 | require_dependency 'raw_html_article' | 2 | require_dependency 'raw_html_article' |
| 3 | require_dependency 'tiny_mce_article' | 3 | require_dependency 'tiny_mce_article' |
| 4 | - | ||
| 5 | require_dependency 'text_article' | 4 | require_dependency 'text_article' |
| 6 | -require_relative '../elasticsearch_indexed_model' | ||
| 7 | - | ||
| 8 | -class TextArticle | ||
| 9 | 5 | ||
| 10 | - def self.profile_hash | ||
| 11 | - { | ||
| 12 | - :id => { type: :integer }, | ||
| 13 | - :visible => { type: :boolean }, | ||
| 14 | - :public_profile => { type: :boolean } | ||
| 15 | - } | ||
| 16 | - end | 6 | +require_relative '../../helpers/searchable_model_helper' |
| 7 | +require_relative '../../helpers/nested_helper/profile' | ||
| 17 | 8 | ||
| 9 | +class TextArticle | ||
| 18 | 10 | ||
| 19 | def self.control_fields | 11 | def self.control_fields |
| 20 | { | 12 | { |
| 21 | :advertise => { type: :boolean }, | 13 | :advertise => { type: :boolean }, |
| 22 | :published => { type: 'boolean'}, | 14 | :published => { type: 'boolean'}, |
| 23 | - :profile => { type: :nested , hash: self.profile_hash } | 15 | + :profile => { type: :nested , hash: NestedProfile.hash } |
| 24 | } | 16 | } |
| 25 | end | 17 | end |
| 26 | 18 | ||
| 27 | - include ElasticsearchIndexedModel | 19 | + def self.should |
| 20 | + [ | ||
| 21 | + { and: [ | ||
| 22 | + { term: { advertise: true }}, | ||
| 23 | + { term: { published: true }} | ||
| 24 | + ] | ||
| 25 | + } | ||
| 26 | + ] | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def self.nested_filter | ||
| 30 | + [ | ||
| 31 | + NestedProfile::filter | ||
| 32 | + ] | ||
| 33 | + end | ||
| 34 | + | ||
| 35 | + include SearchableModelHelper | ||
| 28 | end | 36 | end |
plugins/elasticsearch/lib/ext/uploaded_file.rb
| 1 | require_dependency 'uploaded_file' | 1 | require_dependency 'uploaded_file' |
| 2 | -require_relative '../elasticsearch_indexed_model' | 2 | + |
| 3 | +require_relative '../../helpers/searchable_model_helper' | ||
| 4 | +require_relative '../../helpers/nested_helper/profile' | ||
| 3 | 5 | ||
| 4 | class UploadedFile | 6 | class UploadedFile |
| 5 | def self.control_fields | 7 | def self.control_fields |
| 6 | { | 8 | { |
| 7 | - :advertise => {}, | ||
| 8 | - :published => {}, | ||
| 9 | - :created_at => {type: 'date'} | 9 | + :advertise => {type: :boolean}, |
| 10 | + :published => {type: :boolean}, | ||
| 11 | + :profile => { type: :nested , hash: NestedProfile.hash } | ||
| 10 | } | 12 | } |
| 11 | end | 13 | end |
| 12 | - include ElasticsearchIndexedModel | 14 | + |
| 15 | + def self.should | ||
| 16 | + [ | ||
| 17 | + { and: [ | ||
| 18 | + { term: { advertise: true }}, | ||
| 19 | + { term: { published: true }} | ||
| 20 | + ] | ||
| 21 | + } | ||
| 22 | + ] | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + def self.nested_filter | ||
| 26 | + [ | ||
| 27 | + NestedProfile::filter | ||
| 28 | + ] | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + include SearchableModelHelper | ||
| 13 | end | 32 | end |