smart_search 0.0.75 → 0.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/smart_search.rb +103 -105
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b0296cd89e2bd14fcd295e828bdc3540f58d345
4
- data.tar.gz: 86902f873cad3b93031b1fa6e504f556a46bc0dc
3
+ metadata.gz: 9e50cd7153527e017184f7410525c506b449456e
4
+ data.tar.gz: 8daa5f631fe023f5a4a5745fd94aade9ed129e8e
5
5
  SHA512:
6
- metadata.gz: 10aa6cd5b8e9324434f28bf751bff09ab542afff26dfe459837461de9e6d3484707b83f44a72f61ca0611c7f31bb1d37c98e5aa88f80a25cf888ab951b0bb4e0
7
- data.tar.gz: c561a3d7b7fc27e10b92d240a730a849c39f4e52b1cea32329b5c788570829457665d745f723db2494b650ee3cab7f7510a70f4be54bc404fe3b483005f9dcc6
6
+ metadata.gz: b0b4c41aca0314080ec2c840f49528625e6faa0c550528e16cf5e79fed430649e999e2e1b3cf90e52d44a23a9561b74b2c8372f28a28a563ed8956263db8f2c3
7
+ data.tar.gz: d97d48233d8bf3385d53530a4d924a7f42550c795b636a03177ed1ca402cf4c86d89c5e72589a10828aa7d905fa6ee2f4641c1155d6dcd693d0b7c6f5ba9ef9b
@@ -10,11 +10,11 @@ require "smart_search_tag"
10
10
 
11
11
 
12
12
  module SmartSearch
13
-
13
+
14
14
  def self.included(base)
15
15
  base.extend ClassMethods
16
- end
17
-
16
+ end
17
+
18
18
  # Class Methods for ActiveRecord
19
19
  module ClassMethods
20
20
  # Enable SmartSearch for the current ActiveRecord model.
@@ -28,116 +28,114 @@ module SmartSearch
28
28
  if table_exists?
29
29
  # Check if search_tags exists
30
30
  if !is_smart_search? || options[:force] == true || Rails.env == "test"
31
-
31
+
32
32
  cattr_accessor :condition_default, :group_default, :tags, :order_default, :enable_similarity, :default_template_path
33
33
  send :include, InstanceMethods
34
34
  self.send(:after_save, :create_search_tags, :if => :update_search_tags?) unless options[:auto] == false
35
35
  self.send(:before_destroy, :clear_search_tags)
36
36
  self.enable_similarity ||= true
37
-
37
+
38
38
  attr_accessor :query_score, :dont_update_search_tags
39
-
39
+
40
40
  # options zuweisen
41
41
  if options[:conditions].is_a?(String) && !options[:conditions].blank?
42
42
  self.condition_default = options[:conditions]
43
43
  elsif !options[:conditions].nil?
44
- raise ArgumentError, ":conditions must be a valid SQL Query"
44
+ raise ArgumentError, ":conditions must be a valid SQL Query"
45
45
  else
46
46
  self.condition_default = nil
47
- end
48
-
47
+ end
48
+
49
49
  self.order_default = options[:order]
50
50
 
51
51
  self.tags = options[:on] || []
52
52
  end
53
- end
53
+ end
54
54
  end
55
-
55
+
56
56
  # Verify if SmartSearch already loaded for this model
57
57
  def is_smart_search?
58
58
  self.included_modules.include?(InstanceMethods)
59
59
  end
60
-
60
+
61
61
  # defines where to look for a partial to load when displaying results for this model
62
62
  def result_template_path
63
63
  "/search/results/#{self.name.split("::").last.underscore}"
64
- end
65
-
64
+ end
65
+
66
66
  # Serach database for given search tags
67
67
  def find_by_tags(tags = "", options = {})
68
68
  if self.is_smart_search?
69
-
69
+
70
70
  # Save Data for similarity analysis
71
71
  if tags.size > 3
72
72
  self.connection.execute("INSERT INTO `#{::SmartSearchHistory.table_name}` (`query`) VALUES ('#{tags.gsub(/[^a-zA-ZäöüÖÄÜß\ ]/, '')}');")
73
- end
74
-
75
- tags = tags.split(/[\ -]/).select {|t| !t.blank?}
76
-
73
+ end
74
+
75
+ tags = tags.gsub(/[\(\)\[\]\'\"\*\%]/, '').split(/[\ -]/).select {|t| !t.blank?}
76
+
77
77
  # Fallback for Empty String
78
78
  tags << "#" if tags.empty?
79
-
79
+
80
80
  # Similarity
81
81
  if self.enable_similarity == true
82
- tags.map! do |t|
82
+ tags.map! do |t|
83
83
  similars = SmartSimilarity.similars(t, :increment_counter => true).join("|")
84
84
  "search_tags REGEXP '#{similars}'"
85
- end
86
-
85
+ end
86
+
87
87
  else
88
88
  tags.map! {|t| "search_tags LIKE '%#{t}%'"}
89
- end
90
-
89
+ end
90
+
91
91
  # Load ranking from Search tags
92
92
  result_ids = []
93
93
  result_scores = {}
94
- SmartSearchTag.connection.select_all("select entry_id, sum(boost) as score, group_concat(search_tags) as grouped_tags
95
- from smart_search_tags where `table_name`= '#{self.table_name}' and
96
-
97
- (#{tags.join(' OR ')}) group by entry_id having (#{tags.join(' AND ').gsub('search_tags', 'grouped_tags')}) order by score DESC").each do |r|
98
- result_ids << r["entry_id"].to_i
94
+ SmartSearchTag.connection.select_all("select entry_id, sum(boost) as score, group_concat(search_tags) as grouped_tags
95
+ from smart_search_tags where `table_name`= '#{self.table_name}' and
96
+
97
+ (#{tags.join(' OR ')}) group by entry_id having (#{tags.join(' AND ').gsub('search_tags', 'grouped_tags')}) order by score DESC").each do |r|
98
+ result_ids << r["entry_id"].to_i
99
99
  result_scores[r["entry_id"].to_i] = r['score'].to_f
100
- end
101
-
100
+ end
101
+
102
102
  # Enable unscoped searching
103
103
  if options[:unscoped] == true
104
104
  results = self.unscoped.where(:id => result_ids)
105
- else
105
+ else
106
106
  results = self.where(:id => result_ids)
107
- end
108
-
109
-
110
-
107
+ end
108
+
111
109
  if options[:conditions]
112
110
  results = results.where(options[:conditions])
113
111
  end
114
-
112
+
115
113
  if !self.condition_default.blank?
116
114
  results = results.where(self.condition_default)
117
- end
118
-
119
- if options[:group]
115
+ end
116
+
117
+ if options[:group]
120
118
  results = results.group(options[:group])
121
- end
122
-
119
+ end
120
+
123
121
  if options[:order] || self.order_default
124
122
  results = results.order(options[:order] || self.order_default)
125
123
  else
126
124
  ordered_results = []
127
- results.each do |r|
125
+ results.each do |r|
128
126
  r.query_score = result_scores[r.id]
129
127
  ordered_results[result_ids.index(r.id)] = r
130
- end
131
-
128
+ end
129
+
132
130
  results = ordered_results.compact
133
- end
134
-
131
+ end
132
+
135
133
  return results
136
- else
134
+ else
137
135
  raise "#{self.inspect} is not a SmartSearch"
138
- end
136
+ end
139
137
  end
140
-
138
+
141
139
  # reload search_tags for entire table based on the attributes defined in ':on' option passed to the 'smart_search' method
142
140
  def set_search_index
143
141
  s = self.all.size.to_f
@@ -145,119 +143,119 @@ module SmartSearch
145
143
  a.create_search_tags
146
144
  done = ((i+1).to_f/s)*100
147
145
  printf "Set search index for #{self.name}: #{done}%% \r"
148
- end
149
- end
150
-
146
+ end
147
+ end
148
+
151
149
  # Load all search tags for this table into similarity index
152
150
  def set_similarity_index
153
-
151
+
154
152
  search_tags_list = self.connection.select_all("SELECT search_tags from #{SmartSearchTag.table_name} where `table_name` = #{self.table_name}").map {|r| r["search_tags"]}
155
-
153
+
156
154
  SmartSimilarity.create_from_text(search_tags_list.join(" "))
157
- end
158
-
159
- end
160
-
155
+ end
156
+
157
+ end
158
+
161
159
  # Instance Methods for ActiveRecord
162
160
  module InstanceMethods
163
-
161
+
164
162
  # Load the result template path for this instance
165
163
  def result_template_path
166
164
  self.class.result_template_path
167
- end
168
-
165
+ end
166
+
169
167
  def dont_update_search_tags!
170
168
  self.dont_update_search_tags = true
171
169
  end
172
-
170
+
173
171
  def update_search_tags?
174
172
  !self.dont_update_search_tags
175
- end
176
-
173
+ end
174
+
177
175
  # create search tags for this very record based on the attributes defined in ':on' option passed to the 'Class.smart_search' method
178
176
  def create_search_tags
179
177
  tags = []
180
-
178
+
181
179
  self.class.tags.each do |tag|
182
-
180
+
183
181
  if !tag.is_a?(Hash)
184
- tag = {:field_name => tag, :boost => 1, :search_tags => ""}
182
+ tag = {:field_name => tag, :boost => 1, :search_tags => ""}
185
183
  else
186
184
  tag[:search_tags] = ""
187
185
  tag[:boost] ||= 1
188
- end
189
-
186
+ end
187
+
190
188
  if tag[:field_name].is_a?(Symbol)
191
189
  tag[:search_tags] << self.send(tag[:field_name]).to_s
192
190
  elsif tag[:field_name].is_a?(String)
193
- tag_methods = tag[:field_name].split(".")
191
+ tag_methods = tag[:field_name].split(".")
194
192
  tagx = self.send(tag_methods[0])
195
193
  tag_methods[1..-1].each do |x|
196
194
  tagx = tagx.send(x) rescue ""
197
195
  end
198
- tag[:search_tags] << tagx.to_s
196
+ tag[:search_tags] << tagx.to_s
199
197
  end
200
-
201
- tag[:search_tags] = tag[:search_tags].split(" ").uniq.join(" ").downcase.clear_html
198
+
199
+ tag[:search_tags] = tag[:search_tags].split(" ").uniq.join(" ").downcase.clear_html
202
200
  tags << tag
203
201
  end
204
-
205
-
202
+
203
+
206
204
  self.clear_search_tags
207
-
205
+
208
206
  # Merge search tags with same boost
209
207
  @merged_tags = {}
210
-
208
+
211
209
  tags.each do |t|
212
210
  boost = t[:boost]
213
-
211
+
214
212
  if @merged_tags[boost]
215
-
213
+
216
214
  @merged_tags[boost][:field_name] << ",#{t[:field_name]}"
217
215
  @merged_tags[boost][:search_tags] << " #{t[:search_tags]}"
218
216
  else
219
217
  @merged_tags[boost] = {:field_name => "#{t[:field_name]}", :search_tags => t[:search_tags], :boost => boost }
220
- end
221
-
222
- end
223
-
218
+ end
219
+
220
+ end
221
+
224
222
  @merged_tags.values.each do |t|
225
223
  if !t[:search_tags].blank? && t[:search_tags].size > 1
226
- SmartSearchTag.create(t.merge!(:table_name => self.class.table_name, :entry_id => self.id, :search_tags => t[:search_tags].strip.split(" ").uniq.join(" ")))
227
- end
224
+ SmartSearchTag.create(t.merge!(:table_name => self.class.table_name, :entry_id => self.id, :search_tags => t[:search_tags].strip.split(" ").uniq.join(" ")))
225
+ end
228
226
  end
229
-
227
+
230
228
  end
231
-
229
+
232
230
  # Remove search data for the instance from the index
233
231
  def clear_search_tags
234
232
  if !self.id.nil?
235
233
  SmartSearchTag.connection.execute("DELETE from #{SmartSearchTag.table_name} where `table_name` = '#{self.class.table_name}' and entry_id = #{self.id}")
236
- end
237
- end
238
-
239
- end
240
-
234
+ end
235
+ end
236
+
237
+ end
238
+
241
239
 
242
240
  class Config
243
-
241
+
244
242
  cattr_accessor :search_models
245
243
  cattr_accessor :public_models
246
-
244
+
247
245
  self.search_models = []
248
246
  self.public_models = []
249
-
247
+
250
248
  def self.get_search_models
251
- self.search_models.map {|m| m.constantize}
249
+ self.search_models.map {|m| m.constantize}
252
250
  end
253
-
251
+
254
252
  def self.get_public_models
255
- self.public_models.map {|m| m.constantize}
256
- end
257
-
258
- end
259
-
260
-
253
+ self.public_models.map {|m| m.constantize}
254
+ end
255
+
256
+ end
257
+
258
+
261
259
  end
262
260
 
263
261
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.75
4
+ version: 0.0.76
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Eck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-22 00:00:00.000000000 Z
11
+ date: 2016-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -109,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  version: '0'
110
110
  requirements: []
111
111
  rubyforge_project:
112
- rubygems_version: 2.4.3
112
+ rubygems_version: 2.4.6
113
113
  signing_key:
114
114
  specification_version: 4
115
115
  summary: Simple, easy to use search MySQL based search for ActiveRecord