smart_search 0.0.61 → 0.0.65
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/database.yml +6 -0
- data/lib/smart_search/smart_search_engine.rb +3 -0
- data/lib/smart_search.rb +51 -24
- data/lib/smart_search_ignore_word.rb +28 -0
- data/lib/smart_search_tag.rb +2 -0
- data/lib/smart_similarity.rb +16 -14
- data/lib/tasks/smart_search.rake +29 -1
- data/lib/tasks/testing.rake +27 -0
- data/test/test_document_multi_line.txt +6 -0
- data/test/test_document_one_line.txt +1 -0
- data/test/test_helper.rb +7 -6
- data/test/unit/{smart_search_test.rb → 01_smart_search_test.rb} +5 -3
- data/test/unit/02_smart_search_similarity_test.rb +32 -0
- metadata +27 -18
- data/lib/add_search_tags.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09683d827340bc1dc832274e31723252da084649
|
4
|
+
data.tar.gz: 580b05753d0355b99502205b99276bf71eb6bf58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54a44b78402531aa5098329681e7929f3f97671e42cd5bbe5b517e5143bfa4b9e671179a3d99b537fe8c43de770929ee3c7041be4d2f28197be242bedb774333
|
7
|
+
data.tar.gz: 89df4b626f3f3979a509f637aa5112c6452cf1394108223ba80f603d36534d24331e5864d0ca1d6f85539cf6430cf291a4fdaf385b92bfef6ec17c9358b21fa2
|
data/config/database.yml
ADDED
data/lib/smart_search.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
require "rails"
|
3
|
+
|
2
4
|
require "smart_search"
|
5
|
+
require "smart_search/smart_search_engine"
|
6
|
+
|
3
7
|
require "smart_similarity"
|
4
8
|
require "smart_search_history"
|
5
|
-
require "
|
9
|
+
require "smart_search_tag"
|
6
10
|
|
7
|
-
require "smart_search/smart_search_engine"
|
8
11
|
|
9
12
|
module SmartSearch
|
10
13
|
|
@@ -27,12 +30,9 @@ module SmartSearch
|
|
27
30
|
|
28
31
|
cattr_accessor :condition_default, :group_default, :tags, :order_default, :enable_similarity
|
29
32
|
send :include, InstanceMethods
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
self.send(:before_save, :create_search_tags)
|
34
|
-
|
35
|
-
self.enable_similarity = true
|
33
|
+
self.send(:after_save, :create_search_tags)
|
34
|
+
self.send(:before_destroy, :create_search_tags)
|
35
|
+
self.enable_similarity ||= true
|
36
36
|
|
37
37
|
# options zuweisen
|
38
38
|
if options[:conditions].is_a?(String) && !options[:conditions].blank?
|
@@ -89,8 +89,13 @@ module SmartSearch
|
|
89
89
|
tags.map! {|t| "search_tags LIKE '%#{t}%'"}
|
90
90
|
end
|
91
91
|
|
92
|
+
# Load ranking from Search tags
|
93
|
+
result_ids = SmartSearchTag.connection.select_all("select entry_id, sum(boost), group_concat(search_tags) as grouped_tags
|
94
|
+
from smart_search_tags where `table_name`= '#{self.table_name}' and
|
95
|
+
|
96
|
+
(#{tags.join(' OR ')}) group by entry_id having (#{tags.join(' AND ').gsub('search_tags', 'grouped_tags')}) order by sum(boost) DESC").map {|r| r["entry_id"]}
|
92
97
|
|
93
|
-
results = self.where(
|
98
|
+
results = self.where(:id => result_ids)
|
94
99
|
|
95
100
|
if options[:conditions]
|
96
101
|
results = results.where(options[:conditions])
|
@@ -127,10 +132,10 @@ module SmartSearch
|
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
130
|
-
#
|
135
|
+
# Load all search tags for this table into similarity index
|
131
136
|
def set_similarity_index
|
132
137
|
|
133
|
-
search_tags_list = self.connection.select_all("SELECT search_tags from #{self.table_name}").map {|r| r["search_tags"]}
|
138
|
+
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"]}
|
134
139
|
|
135
140
|
SmartSimilarity.create_from_text(search_tags_list.join(" "))
|
136
141
|
end
|
@@ -145,29 +150,51 @@ module SmartSearch
|
|
145
150
|
|
146
151
|
# create search tags for this very record based on the attributes defined in ':on' option passed to the 'Class.smart_search' method
|
147
152
|
def create_search_tags
|
148
|
-
tags
|
153
|
+
tags = []
|
154
|
+
|
149
155
|
self.class.tags.each do |tag|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
156
|
+
|
157
|
+
if !tag.is_a?(Hash)
|
158
|
+
tag = {:field_name => tag, :boost => 1, :search_tags => ""}
|
159
|
+
else
|
160
|
+
tag[:search_tags] = ""
|
161
|
+
tag[:boost] ||= 1
|
162
|
+
end
|
163
|
+
|
164
|
+
if tag[:field_name].is_a?(Symbol)
|
165
|
+
tag[:search_tags] << self.send(tag[:field_name]).to_s
|
166
|
+
elsif tag[:field_name].is_a?(String)
|
167
|
+
tag_methods = tag[:field_name].split(".")
|
154
168
|
tagx = self.send(tag_methods[0])
|
155
169
|
tag_methods[1..-1].each do |x|
|
156
170
|
tagx = tagx.send(x) rescue ""
|
157
171
|
end
|
158
|
-
|
159
|
-
end
|
172
|
+
tag[:search_tags] << tagx.to_s
|
173
|
+
end
|
174
|
+
|
175
|
+
tag[:search_tags] = tag[:search_tags].split(" ").uniq.join(" ").downcase
|
176
|
+
tags << tag
|
160
177
|
end
|
161
|
-
searchtags = tags.join(" ").split(" ")
|
162
|
-
searchtags = searchtags.uniq.join(" ")
|
163
|
-
search_tags_min = searchtags.gsub(" ", "").downcase
|
164
178
|
|
165
|
-
|
166
|
-
|
179
|
+
|
180
|
+
self.clear_search_tags
|
181
|
+
|
182
|
+
tags.each do |t|
|
183
|
+
SmartSearchTag.create(t.merge!(:table_name => self.class.table_name, :entry_id => self.id))
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
def clear_search_tags
|
190
|
+
if !self.id.nil?
|
191
|
+
SmartSearchTag.connection.execute("DELETE from #{SmartSearchTag.table_name} where `table_name` = '#{self.class.table_name}' and entry_id = #{self.id}")
|
192
|
+
end
|
193
|
+
end
|
167
194
|
|
168
195
|
end
|
169
196
|
|
170
|
-
|
197
|
+
|
171
198
|
class Config
|
172
199
|
|
173
200
|
cattr_accessor :search_models
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class SmartSearchIgnoreWord < ActiveRecord::Base
|
2
|
+
|
3
|
+
#= Configuration
|
4
|
+
self.table_name = "smart_search_ignore_words"
|
5
|
+
#== Associations
|
6
|
+
# => Stuff in Here
|
7
|
+
|
8
|
+
#== Plugins and modules
|
9
|
+
#=== PlugIns
|
10
|
+
# => Stuff in Here
|
11
|
+
|
12
|
+
#=== include Modules
|
13
|
+
# => Stuff in Here
|
14
|
+
|
15
|
+
#== Konstanten
|
16
|
+
# => Stuff in Here
|
17
|
+
|
18
|
+
#== Validation and Callbacks
|
19
|
+
#=== Validation
|
20
|
+
validates_uniqueness_of :word
|
21
|
+
|
22
|
+
#=== Callbacks
|
23
|
+
# => Stuff in Here
|
24
|
+
|
25
|
+
|
26
|
+
# => END
|
27
|
+
|
28
|
+
end
|
data/lib/smart_similarity.rb
CHANGED
@@ -3,7 +3,6 @@ class SmartSimilarity < ActiveRecord::Base
|
|
3
3
|
#= Configuration
|
4
4
|
serialize :similarities, Array
|
5
5
|
self.table_name = "smart_search_similarities"
|
6
|
-
require "amatch"
|
7
6
|
|
8
7
|
#== Associations
|
9
8
|
# => Stuff in Here
|
@@ -28,6 +27,8 @@ class SmartSimilarity < ActiveRecord::Base
|
|
28
27
|
# Limit Number of similar words
|
29
28
|
SIMILARITY_LIMIT = 8
|
30
29
|
|
30
|
+
SPLITTING_REGEXP = /\b/
|
31
|
+
|
31
32
|
#== Validation and Callbacks
|
32
33
|
#=== Validation
|
33
34
|
|
@@ -39,7 +40,7 @@ class SmartSimilarity < ActiveRecord::Base
|
|
39
40
|
# This method is used to generate date from every source, e.g. file, url, single words etc..
|
40
41
|
def self.create_from_text(text)
|
41
42
|
# prepare text
|
42
|
-
prepared_text = text.downcase.split(
|
43
|
+
prepared_text = text.downcase.split(SPLITTING_REGEXP).uniq
|
43
44
|
prepared_text = prepared_text.select {|w| w.size >= 3 && !w.match(/[0-9\-_<>\.\/(){}&\?"'@*+$!=,:'#;]/)}
|
44
45
|
list = {}
|
45
46
|
prepared_text.each do |word|
|
@@ -78,18 +79,19 @@ class SmartSimilarity < ActiveRecord::Base
|
|
78
79
|
# Best used for loading big dictionary files.
|
79
80
|
# Uses 'spawnling' to split the data into 8 stacks and load them simultaniously
|
80
81
|
def self.load_file(path)
|
81
|
-
count = %x{wc -l #{path}}.split[0].to_i
|
82
|
+
count = %x{wc -l #{path}}.split[0].to_i.max(1)
|
82
83
|
puts "loading file: #{path}"
|
83
84
|
puts "=> #{count} rows"
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
85
|
+
|
86
|
+
if count == 1
|
87
|
+
File.open(path, "r").read.split(SPLITTING_REGEXP).each {|w| self.add_word(w)}
|
88
|
+
else
|
89
|
+
File.open(path, "r").read.split(SPLITTING_REGEXP).seperate([8,count].min).each_with_index do |stack, si|
|
90
|
+
stack.each_with_index do |l,i|
|
91
|
+
self.add_word(l)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
93
95
|
end
|
94
96
|
|
95
97
|
# Load words from website and save them to index
|
@@ -99,7 +101,7 @@ class SmartSimilarity < ActiveRecord::Base
|
|
99
101
|
|
100
102
|
# Loads your created query history and saves them to the index
|
101
103
|
def self.load_from_query_history
|
102
|
-
queries =
|
104
|
+
queries = ActiveRecord::Base.connection.select_all("SELECT query from `#{::SmartSearchHistory.table_name}`").map {|r| r["query"]}.join(" ")
|
103
105
|
self.create_from_text(queries)
|
104
106
|
self.connection.execute("TRUNCATE `#{::SmartSearchHistory.table_name}`")
|
105
107
|
end
|
@@ -110,7 +112,7 @@ class SmartSimilarity < ActiveRecord::Base
|
|
110
112
|
if list.nil?
|
111
113
|
return [word]
|
112
114
|
else
|
113
|
-
self.
|
115
|
+
self.connection.execute("UPDATE `smart_search_similarities` SET `count` = #{list.count+1} where `smart_search_similarities`.`phrase` = '#{list.phrase}'")
|
114
116
|
return [word, list.similarities].flatten
|
115
117
|
end
|
116
118
|
end
|
data/lib/tasks/smart_search.rake
CHANGED
@@ -26,5 +26,33 @@ namespace :smart_search do
|
|
26
26
|
SmartSimilarity.load_url(ENV['URL'])
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
desc "load ignore words list"
|
33
|
+
task :load_ignore_words => :environment do
|
34
|
+
require File.expand_path("../../smart_search_ignore_word", __FILE__)
|
35
|
+
|
36
|
+
dic_path = File.expand_path("../../../dictionaries/*", __FILE__)
|
37
|
+
|
38
|
+
raise dic_path.inspect
|
39
|
+
|
40
|
+
dic_folders = Dir.glob(dic_path).select {|d| File.directory?(d)}
|
41
|
+
|
42
|
+
dic_folders.each do |folder|
|
43
|
+
locale = folder.split("/").last
|
44
|
+
word_file = File.join(folder, "#{locale}.ignore_words.dic")
|
45
|
+
if File.exists?(word_file)
|
46
|
+
File.open(word_file, "r").each_line do |word|
|
47
|
+
SmartSearchIgnoreWord.create(:word => word.strip.downcase, :locale => locale)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
29
55
|
|
30
|
-
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "active_record"
|
2
|
+
namespace :db do
|
3
|
+
desc "Create test database. Overwrite dasebase config with USERNAME=, PASSWORD=, DATABASE="
|
4
|
+
task :create_test_db do
|
5
|
+
config = YAML::load(File.open(File.expand_path("config/database.yml")))["test"]
|
6
|
+
|
7
|
+
# Overwrite config
|
8
|
+
config.merge!('database' => ENV['DATABASE']) if ENV['DATABASE']
|
9
|
+
config.merge!('username' => ENV['USERNAME']) if ENV['USERNAME']
|
10
|
+
config.merge!('password' => ENV['PASSWORD']) if ENV['PASSWORD']
|
11
|
+
|
12
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
|
13
|
+
ActiveRecord::Base.connection.drop_database(config['database']) rescue nil
|
14
|
+
ActiveRecord::Base.connection.create_database(config['database'])
|
15
|
+
ActiveRecord::Base.establish_connection(config)
|
16
|
+
end
|
17
|
+
|
18
|
+
task :migrate do
|
19
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
task :test_smart_search do
|
24
|
+
Rake::Task["db:create_test_db"].execute
|
25
|
+
Rake::Task["db:migrate"].execute
|
26
|
+
Rake::Task["test"].execute
|
27
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
The quick brown fox jumps over the lazy dog.
|
2
|
+
The five boxing wizards jump quickly.
|
3
|
+
Sphinx of all black quartz judge my vow.
|
4
|
+
A quick movement of the enemy will jeopardize six gunboats.
|
5
|
+
Five quacking Zephyrs jolt my wax bed.
|
6
|
+
Heavy boxes perform waltzes and jigs.
|
@@ -0,0 +1 @@
|
|
1
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
data/test/test_helper.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'rubygems'
|
3
|
+
require 'bundler'
|
3
4
|
require 'test/unit'
|
4
5
|
require 'active_support'
|
5
6
|
require 'active_record'
|
6
7
|
require 'active_model'
|
7
8
|
|
8
9
|
require "smart_search"
|
9
|
-
require "
|
10
|
+
require "smart_search/smart_search_engine"
|
10
11
|
|
11
|
-
|
12
|
+
|
13
|
+
ActiveRecord::Base.establish_connection(:adapter => "mysql2", :database => "smart_search_test")
|
12
14
|
|
13
15
|
ActiveRecord::Schema.define(:version => 1) do
|
14
16
|
create_table :users do |t|
|
@@ -16,7 +18,6 @@ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":me
|
|
16
18
|
t.string :last_name
|
17
19
|
t.integer :office_id
|
18
20
|
t.date :birthday
|
19
|
-
t.text :search_tags
|
20
21
|
t.timestamps
|
21
22
|
end
|
22
23
|
|
@@ -25,15 +26,15 @@ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":me
|
|
25
26
|
t.string :last_name
|
26
27
|
t.integer :user_id
|
27
28
|
t.date :birthday
|
28
|
-
t.text :search_tags
|
29
29
|
t.timestamps
|
30
30
|
end
|
31
31
|
|
32
32
|
create_table :offices do |t|
|
33
33
|
t.string :name
|
34
|
-
t.text :search_tags
|
35
34
|
t.timestamps
|
36
|
-
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
37
38
|
end
|
38
39
|
#
|
39
40
|
# def drop_db
|
@@ -6,6 +6,8 @@ class SmartSearchTest < Test::Unit::TestCase
|
|
6
6
|
office_name = "Office1"
|
7
7
|
office = Office.create(:name => office_name)
|
8
8
|
|
9
|
+
Office.enable_similarity = false
|
10
|
+
|
9
11
|
assert_equal office, Office.find_by_tags(office_name).first
|
10
12
|
end
|
11
13
|
|
@@ -36,6 +38,7 @@ class SmartSearchTest < Test::Unit::TestCase
|
|
36
38
|
office_id_nok = 5
|
37
39
|
|
38
40
|
User.smart_search :on => [:full_name], :conditions => "office_id <> #{office_id_nok}", :force => true
|
41
|
+
User.enable_similarity = false
|
39
42
|
|
40
43
|
user = User.create(:first_name => "Unknown", :last_name => "User", :office_id => office_id_nok)
|
41
44
|
user = User.create(:first_name => "Public", :last_name => "User", :office_id => office_id_ok)
|
@@ -46,6 +49,7 @@ class SmartSearchTest < Test::Unit::TestCase
|
|
46
49
|
|
47
50
|
def test_should_use_default_order_and_order_should_be_overwriteable
|
48
51
|
User.smart_search :on => [:full_name], :order => :first_name, :force => true
|
52
|
+
User.enable_similarity = false
|
49
53
|
|
50
54
|
user_c = User.create(:first_name => "C", :last_name => "Test1")
|
51
55
|
user_a = User.create(:first_name => "A", :last_name => "Test3")
|
@@ -65,9 +69,7 @@ class SmartSearchTest < Test::Unit::TestCase
|
|
65
69
|
user_b = User.create(:first_name => "B", :last_name => "Next2")
|
66
70
|
|
67
71
|
assert_equal [], User.find_by_tags("A").where("last_name <> 'Bah' ")
|
68
|
-
end
|
69
|
-
|
70
|
-
|
72
|
+
end
|
71
73
|
|
72
74
|
|
73
75
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require "test_helper"
|
3
|
+
class SmartSearchSimilartyTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_similarity_should_load_from_file
|
6
|
+
testfile_1 = File.expand_path("../../test_document_one_line.txt", __FILE__)
|
7
|
+
testfile_2 = File.expand_path("../../test_document_multi_line.txt", __FILE__)
|
8
|
+
SmartSimilarity.connection.execute "Truncate table #{SmartSimilarity.table_name}"
|
9
|
+
|
10
|
+
assert_equal 0, SmartSimilarity.count
|
11
|
+
SmartSimilarity.load_file(testfile_2)
|
12
|
+
new_count = SmartSimilarity.count
|
13
|
+
assert_not_equal 0, new_count
|
14
|
+
|
15
|
+
SmartSimilarity.load_file(testfile_1)
|
16
|
+
assert_not_equal new_count, SmartSimilarity.count
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_similarity_should_load_from_url
|
20
|
+
count = SmartSimilarity.count
|
21
|
+
SmartSimilarity.load_url("https://github.com/florianeck/smart_search")
|
22
|
+
assert_not_equal count, SmartSimilarity.count
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_similarity_should_load_from_history
|
26
|
+
count = SmartSimilarity.count
|
27
|
+
User.find_by_tags("this is history now")
|
28
|
+
SmartSimilarity.load_from_query_history
|
29
|
+
assert_not_equal count, SmartSimilarity.count
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
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.
|
4
|
+
version: 0.0.65
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Eck
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -39,49 +39,55 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: friendly_extensions
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.0.61
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.0.61
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: mysql2
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
61
|
+
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
69
|
-
description:
|
70
|
-
|
68
|
+
version: '0'
|
69
|
+
description: SmartSearch adds full-text search functions to ActiveRecord, including
|
70
|
+
search for similiar words. Its fast, simple, and works with almost zero-config!
|
71
71
|
email: it-support@friends-systems.de
|
72
72
|
executables: []
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
+
- config/database.yml
|
76
77
|
- config/routes.rb
|
77
|
-
- lib/add_search_tags.rb
|
78
78
|
- lib/smart_search.rb
|
79
79
|
- lib/smart_search/smart_search_engine.rb
|
80
80
|
- lib/smart_search_history.rb
|
81
|
+
- lib/smart_search_ignore_word.rb
|
82
|
+
- lib/smart_search_tag.rb
|
81
83
|
- lib/smart_similarity.rb
|
82
84
|
- lib/tasks/smart_search.rake
|
85
|
+
- lib/tasks/testing.rake
|
86
|
+
- test/test_document_multi_line.txt
|
87
|
+
- test/test_document_one_line.txt
|
83
88
|
- test/test_helper.rb
|
84
|
-
- test/unit/
|
89
|
+
- test/unit/01_smart_search_test.rb
|
90
|
+
- test/unit/02_smart_search_similarity_test.rb
|
85
91
|
homepage: https://rubygems.org/gems/smart_search
|
86
92
|
licenses: []
|
87
93
|
metadata: {}
|
@@ -104,7 +110,10 @@ rubyforge_project:
|
|
104
110
|
rubygems_version: 2.2.1
|
105
111
|
signing_key:
|
106
112
|
specification_version: 4
|
107
|
-
summary: Simple, easy to use search
|
113
|
+
summary: Simple, easy to use search MySQL based search for ActiveRecord
|
108
114
|
test_files:
|
115
|
+
- test/test_document_multi_line.txt
|
116
|
+
- test/test_document_one_line.txt
|
109
117
|
- test/test_helper.rb
|
110
|
-
- test/unit/
|
118
|
+
- test/unit/01_smart_search_test.rb
|
119
|
+
- test/unit/02_smart_search_similarity_test.rb
|