Commit 6a5169969ef4cb072abbb66512f8d6960fa963cc

Authored by Macartur Sousa
1 parent 3224ddef

Elasticsearch: Adding filter

* Filter by environment
* Filter by visible community

Signed-off-by: Macartur Sousa <macartur.sc@gmail.com>
plugins/elasticsearch/helpers/elasticsearch_helper.rb
... ... @@ -63,31 +63,42 @@ module ElasticsearchHelper
63 63 end
64 64 end
65 65  
66   - def query_method expression="", fields=[]
67   - query_exp = {}
68   - if expression.blank?
69   - else
70   - query_exp = {
71   - query: {
72   - query_string: {
73   - query: "*"+expression.downcase.split.join('* *')+"*",
74   - fields: fields,
75   - tie_breaker: 0.4,
76   - minimum_should_match: "100%"
77   - },
  66 + def query_string expression="", models=[]
  67 + return { match_all: {} } if not expression
  68 +
  69 + {
  70 + query_string: {
  71 + query: "*"+expression.downcase.split.join('* *')+"*",
  72 + fields: fields_from_models(models),
  73 + tie_breaker: 0.4,
  74 + minimum_should_match: "100%"
  75 + }
  76 + }
  77 + end
  78 +
  79 +
  80 + def query_method expression="", models=[]
  81 + {
  82 + query: {
  83 + filtered: {
  84 + query: query_string(expression,models),
  85 + filter: {
  86 + bool: {
  87 + should: models.map {|model| model.filter(environment: @environment.id)}
  88 + }
  89 + }
78 90 }
79 91 }
80   - end
81   - query_exp
  92 + }
82 93 end
83 94  
84 95 def get_query text="", options={}
85 96 klass = options[:klass]
86 97 sort_by = options[:sort_by]
87 98  
88   - fields = klass.nil? ? (fields_from_models searchable_models) : (fields_from_models [klass])
  99 + models = (klass.nil?) ? searchable_models : [klass]
89 100  
90   - query = query_method(text, fields)
  101 + query = query_method(text, models)
91 102 query[:sort] = sort_by if sort_by
92 103 query
93 104 end
... ...
plugins/elasticsearch/lib/elasticsearch_indexed_model.rb
  1 +require_relative 'nested_environment'
  2 +
1 3 module ElasticsearchIndexedModel
2 4  
3 5 def self.included base
... ... @@ -5,17 +7,24 @@ module ElasticsearchIndexedModel
5 7 base.send :include, Elasticsearch::Model::Callbacks
6 8  
7 9 base.send :index_name, "#{Rails.env}_#{base.index_name}"
  10 +
8 11 base.extend ClassMethods
  12 + base.send :include, InstanceMethods
  13 +
9 14 base.class_eval do
10 15 settings index: { number_of_shards: 1 } do
11 16 mappings dynamic: 'false' do
12 17 base.indexed_fields.each do |field, value|
13   - value = {} if value.nil?
14   - type = value[:type].presence
15   - if type.nil?
16   - indexes(field, fields: base.raw_field(field))
  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
17 26 else
18   - indexes field, type: type
  27 + indexes(field, base.indexes_as_hash(field,type))
19 28 end
20 29 print '.'
21 30 end
... ... @@ -35,7 +44,18 @@ module ElasticsearchIndexedModel
35 44 end
36 45  
37 46 module ClassMethods
38   - def raw_field name
  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
39 59 {
40 60 raw: {
41 61 type: "string",
... ... @@ -45,9 +65,61 @@ module ElasticsearchIndexedModel
45 65 end
46 66  
47 67 def indexed_fields
48   - self::SEARCHABLE_FIELDS.merge self.control_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 + }
49 90 end
50 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
51 123 end
52 124  
53 125 end
... ...
plugins/elasticsearch/lib/ext/community.rb
... ... @@ -2,10 +2,23 @@ require_dependency &#39;community&#39;
2 2 require_relative '../elasticsearch_indexed_model'
3 3  
4 4 class Community
  5 +
5 6 def self.control_fields
6 7 {
7   - :created_at => {type: 'date'}
  8 + :secret => { type: :boolean },
  9 + :visible => { type: :boolean },
8 10 }
9 11 end
  12 +
  13 + # community visible
  14 + def self.should_and
  15 + [
  16 + {term: { :secret => false }},
  17 + {term: { :visible => true }}
  18 + ]
  19 + end
  20 +
  21 +
10 22 include ElasticsearchIndexedModel
  23 +
11 24 end
... ...
plugins/elasticsearch/lib/ext/person.rb
... ... @@ -4,9 +4,9 @@ require_relative &#39;../elasticsearch_indexed_model&#39;
4 4 class Person
5 5 def self.control_fields
6 6 {
7   - :visible => {type: 'boolean'},
  7 + :visible => {type: 'boolean'},
8 8 :public_profile => {type: 'boolean'},
9   - :created_at => {type: 'date'}
  9 + :created_at => {type: 'date'}
10 10 }
11 11 end
12 12 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/lib/ext/text_article.rb
... ... @@ -6,12 +6,23 @@ require_dependency &#39;text_article&#39;
6 6 require_relative '../elasticsearch_indexed_model'
7 7  
8 8 class TextArticle
  9 +
  10 + def self.profile_hash
  11 + {
  12 + :id => { type: :integer },
  13 + :visible => { type: :boolean },
  14 + :public_profile => { type: :boolean }
  15 + }
  16 + end
  17 +
  18 +
9 19 def self.control_fields
10 20 {
11   - :advertise => {},
12   - :published => {},
13   - :created_at => {type: 'date'}
  21 + :advertise => { type: :boolean },
  22 + :published => { type: 'boolean'},
  23 + :profile => { type: :nested , hash: self.profile_hash }
14 24 }
15 25 end
  26 +
16 27 include ElasticsearchIndexedModel
17 28 end
... ...
plugins/elasticsearch/lib/nested_environment.rb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +module NestedEnvironment
  2 + def self.environment_hash
  3 + {
  4 + :id => { type: :integer },
  5 + :is_default => {type: :boolean }
  6 + }
  7 + end
  8 +end
... ...