searchkick 0.5.3 → 0.6.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -0
- data/README.md +17 -3
- data/gemfiles/mongoid4.gemfile +1 -1
- data/lib/searchkick.rb +12 -2
- data/lib/searchkick/index.rb +67 -0
- data/lib/searchkick/model.rb +8 -4
- data/lib/searchkick/query.rb +441 -0
- data/lib/searchkick/reindex.rb +15 -23
- data/lib/searchkick/results.rb +81 -6
- data/lib/searchkick/search.rb +4 -387
- data/lib/searchkick/similar.rb +1 -1
- data/lib/searchkick/version.rb +1 -1
- data/searchkick.gemspec +5 -6
- data/test/index_test.rb +6 -3
- data/test/query_test.rb +14 -0
- data/test/sql_test.rb +16 -6
- data/test/test_helper.rb +6 -8
- metadata +24 -33
- data/lib/searchkick/logger.rb +0 -19
data/lib/searchkick/similar.rb
CHANGED
@@ -3,7 +3,7 @@ module Searchkick
|
|
3
3
|
|
4
4
|
def similar(options = {})
|
5
5
|
like_text = self.class.searchkick_index.retrieve(document_type, id).to_hash
|
6
|
-
.keep_if{|k,v|
|
6
|
+
.keep_if{|k,v| !options[:fields] || options[:fields].map(&:to_s).include?(k) }
|
7
7
|
.values.compact.join(" ")
|
8
8
|
|
9
9
|
# TODO deep merge method
|
data/lib/searchkick/version.rb
CHANGED
data/searchkick.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Searchkick::VERSION
|
9
9
|
spec.authors = ["Andrew Kane"]
|
10
10
|
spec.email = ["andrew@chartkick.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
11
|
+
spec.description = %q{Intelligent search made easy}
|
12
|
+
spec.summary = %q{Searchkick learns what your users are looking for. As more people search, it gets smarter and the results get better. It’s friendly for developers - and magical for your users.}
|
13
13
|
spec.homepage = "https://github.com/ankane/searchkick"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -18,12 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "
|
22
|
-
spec.add_dependency "
|
21
|
+
spec.add_dependency "activemodel"
|
22
|
+
spec.add_dependency "elasticsearch"
|
23
|
+
spec.add_dependency "patron" # persistent http connections for performance
|
23
24
|
|
24
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
26
|
spec.add_development_dependency "rake"
|
26
27
|
spec.add_development_dependency "minitest", "~> 4.7"
|
27
|
-
spec.add_development_dependency "activerecord"
|
28
|
-
spec.add_development_dependency "pg"
|
29
28
|
end
|
data/test/index_test.rb
CHANGED
@@ -3,8 +3,11 @@ require_relative "test_helper"
|
|
3
3
|
class TestIndex < Minitest::Unit::TestCase
|
4
4
|
|
5
5
|
def test_clean_indices
|
6
|
-
old_index =
|
7
|
-
different_index =
|
6
|
+
old_index = Searchkick::Index.new("products_test_20130801000000000")
|
7
|
+
different_index = Searchkick::Index.new("items_test_20130801000000000")
|
8
|
+
|
9
|
+
old_index.delete if old_index.exists?
|
10
|
+
different_index.delete if different_index.exists?
|
8
11
|
|
9
12
|
# create indexes
|
10
13
|
old_index.create
|
@@ -18,7 +21,7 @@ class TestIndex < Minitest::Unit::TestCase
|
|
18
21
|
end
|
19
22
|
|
20
23
|
def test_clean_indices_old_format
|
21
|
-
old_index =
|
24
|
+
old_index = Searchkick::Index.new("products_test_20130801000000")
|
22
25
|
old_index.create
|
23
26
|
|
24
27
|
Product.clean_indices
|
data/test/query_test.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class TestQuery < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_basic
|
6
|
+
store_names ["Milk", "Apple"]
|
7
|
+
query = Product.search("milk", execute: false)
|
8
|
+
# query.body = {query: {match_all: {}}}
|
9
|
+
# query.body = {query: {match: {name: "Apple"}}}
|
10
|
+
query.body[:query] = {match_all: {}}
|
11
|
+
assert_equal ["Apple", "Milk"], query.execute.map(&:name).sort
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/test/sql_test.rb
CHANGED
@@ -26,6 +26,8 @@ class TestSql < Minitest::Unit::TestCase
|
|
26
26
|
assert_equal 2, products.per_page
|
27
27
|
assert_equal 3, products.total_pages
|
28
28
|
assert_equal 5, products.total_count
|
29
|
+
assert_equal 2, products.limit_value
|
30
|
+
assert_equal 4, products.offset_value
|
29
31
|
end
|
30
32
|
|
31
33
|
def test_pagination_nil_page
|
@@ -40,7 +42,7 @@ class TestSql < Minitest::Unit::TestCase
|
|
40
42
|
store [
|
41
43
|
{name: "Product A", store_id: 1, in_stock: true, backordered: true, created_at: now, orders_count: 4, user_ids: [1, 2, 3]},
|
42
44
|
{name: "Product B", store_id: 2, in_stock: true, backordered: false, created_at: now - 1, orders_count: 3, user_ids: [1]},
|
43
|
-
{name: "Product C", store_id: 3, in_stock: false, backordered: true, created_at: now - 2, orders_count: 2},
|
45
|
+
{name: "Product C", store_id: 3, in_stock: false, backordered: true, created_at: now - 2, orders_count: 2, user_ids: [1, 3]},
|
44
46
|
{name: "Product D", store_id: 4, in_stock: false, backordered: false, created_at: now - 3, orders_count: 1},
|
45
47
|
]
|
46
48
|
assert_search "product", ["Product A", "Product B"], where: {in_stock: true}
|
@@ -66,11 +68,13 @@ class TestSql < Minitest::Unit::TestCase
|
|
66
68
|
assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{orders_count: [2, 4]}, {store_id: [1, 2]}]]}
|
67
69
|
assert_search "product", ["Product A", "Product D"], where: {or: [[{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]]}
|
68
70
|
# all
|
69
|
-
assert_search "product", ["Product A"], where: {user_ids: {all: [1, 3]}}
|
71
|
+
assert_search "product", ["Product A", "Product C"], where: {user_ids: {all: [1, 3]}}
|
70
72
|
assert_search "product", [], where: {user_ids: {all: [1, 2, 3, 4]}}
|
73
|
+
# any / nested terms
|
74
|
+
assert_search "product", ["Product B", "Product C"], where: {user_ids: {not: [2], in: [1,3]}}
|
71
75
|
# not / exists
|
72
|
-
assert_search "product", ["Product
|
73
|
-
assert_search "product", ["Product A", "Product B"], where: {user_ids: {not: nil}}
|
76
|
+
assert_search "product", ["Product D"], where: {user_ids: nil}
|
77
|
+
assert_search "product", ["Product A", "Product B", "Product C"], where: {user_ids: {not: nil}}
|
74
78
|
assert_search "product", ["Product A", "Product C", "Product D"], where: {user_ids: [3, nil]}
|
75
79
|
assert_search "product", ["Product B"], where: {user_ids: {not: [3, nil]}}
|
76
80
|
end
|
@@ -190,6 +194,12 @@ class TestSql < Minitest::Unit::TestCase
|
|
190
194
|
assert_search "fresh honey", ["Honey"], partial: true
|
191
195
|
end
|
192
196
|
|
197
|
+
def test_operator
|
198
|
+
store_names ["Honey"]
|
199
|
+
assert_search "fresh honey", []
|
200
|
+
assert_search "fresh honey", ["Honey"], operator: "or"
|
201
|
+
end
|
202
|
+
|
193
203
|
def test_misspellings
|
194
204
|
store_names ["abc", "abd", "aee"]
|
195
205
|
assert_search "abc", ["abc"], misspellings: false
|
@@ -237,12 +247,12 @@ class TestSql < Minitest::Unit::TestCase
|
|
237
247
|
|
238
248
|
def test_load_false
|
239
249
|
store_names ["Product A"]
|
240
|
-
assert_kind_of
|
250
|
+
assert_kind_of Hash, Product.search("product", load: false).first
|
241
251
|
end
|
242
252
|
|
243
253
|
def test_load_false_with_include
|
244
254
|
store_names ["Product A"]
|
245
|
-
assert_kind_of
|
255
|
+
assert_kind_of Hash, Product.search("product", load: false, include: [:store]).first
|
246
256
|
end
|
247
257
|
|
248
258
|
# TODO see if Mongoid is loaded
|
data/test/test_helper.rb
CHANGED
@@ -2,14 +2,12 @@ require "bundler/setup"
|
|
2
2
|
Bundler.require(:default)
|
3
3
|
require "minitest/autorun"
|
4
4
|
require "minitest/pride"
|
5
|
+
require "logger"
|
5
6
|
|
6
7
|
ENV["RACK_ENV"] = "test"
|
7
8
|
|
8
9
|
File.delete("elasticsearch.log") if File.exists?("elasticsearch.log")
|
9
|
-
|
10
|
-
logger "elasticsearch.log", :level => "debug"
|
11
|
-
pretty true
|
12
|
-
end
|
10
|
+
Searchkick.client.transport.logger = Logger.new("elasticsearch.log")
|
13
11
|
|
14
12
|
if defined?(Mongoid)
|
15
13
|
Mongoid.configure do |config|
|
@@ -59,9 +57,9 @@ else
|
|
59
57
|
ActiveRecord::Base.time_zone_aware_attributes = true
|
60
58
|
|
61
59
|
# migrations
|
62
|
-
ActiveRecord::Base.establish_connection :
|
60
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
63
61
|
|
64
|
-
ActiveRecord::Migration.create_table :products
|
62
|
+
ActiveRecord::Migration.create_table :products do |t|
|
65
63
|
t.string :name
|
66
64
|
t.integer :store_id
|
67
65
|
t.boolean :in_stock
|
@@ -74,11 +72,11 @@ else
|
|
74
72
|
t.timestamps
|
75
73
|
end
|
76
74
|
|
77
|
-
ActiveRecord::Migration.create_table :stores
|
75
|
+
ActiveRecord::Migration.create_table :stores do |t|
|
78
76
|
t.string :name
|
79
77
|
end
|
80
78
|
|
81
|
-
ActiveRecord::Migration.create_table :animals
|
79
|
+
ActiveRecord::Migration.create_table :animals do |t|
|
82
80
|
t.string :name
|
83
81
|
t.string :type
|
84
82
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: searchkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activemodel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: elasticsearch
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,27 +39,13 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.3'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.3'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake
|
42
|
+
name: patron
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '0'
|
62
|
-
type: :
|
48
|
+
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
@@ -67,21 +53,21 @@ dependencies:
|
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
56
|
+
name: bundler
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '1.3'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '1.3'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: rake
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
@@ -95,20 +81,20 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
84
|
+
name: minitest
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
89
|
+
version: '4.7'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
111
|
-
description:
|
96
|
+
version: '4.7'
|
97
|
+
description: Intelligent search made easy
|
112
98
|
email:
|
113
99
|
- andrew@chartkick.com
|
114
100
|
executables: []
|
@@ -125,8 +111,9 @@ files:
|
|
125
111
|
- gemfiles/mongoid3.gemfile
|
126
112
|
- gemfiles/mongoid4.gemfile
|
127
113
|
- lib/searchkick.rb
|
128
|
-
- lib/searchkick/
|
114
|
+
- lib/searchkick/index.rb
|
129
115
|
- lib/searchkick/model.rb
|
116
|
+
- lib/searchkick/query.rb
|
130
117
|
- lib/searchkick/reindex.rb
|
131
118
|
- lib/searchkick/results.rb
|
132
119
|
- lib/searchkick/search.rb
|
@@ -142,6 +129,7 @@ files:
|
|
142
129
|
- test/inheritance_test.rb
|
143
130
|
- test/match_test.rb
|
144
131
|
- test/model_test.rb
|
132
|
+
- test/query_test.rb
|
145
133
|
- test/should_index_test.rb
|
146
134
|
- test/similar_test.rb
|
147
135
|
- test/sql_test.rb
|
@@ -168,10 +156,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
156
|
version: '0'
|
169
157
|
requirements: []
|
170
158
|
rubyforge_project:
|
171
|
-
rubygems_version: 2.2.
|
159
|
+
rubygems_version: 2.2.2
|
172
160
|
signing_key:
|
173
161
|
specification_version: 4
|
174
|
-
summary:
|
162
|
+
summary: Searchkick learns what your users are looking for. As more people search,
|
163
|
+
it gets smarter and the results get better. It’s friendly for developers - and magical
|
164
|
+
for your users.
|
175
165
|
test_files:
|
176
166
|
- test/autocomplete_test.rb
|
177
167
|
- test/boost_test.rb
|
@@ -181,6 +171,7 @@ test_files:
|
|
181
171
|
- test/inheritance_test.rb
|
182
172
|
- test/match_test.rb
|
183
173
|
- test/model_test.rb
|
174
|
+
- test/query_test.rb
|
184
175
|
- test/should_index_test.rb
|
185
176
|
- test/similar_test.rb
|
186
177
|
- test/sql_test.rb
|
data/lib/searchkick/logger.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require "tire/rails/logger"
|
2
|
-
require "tire/rails/logger/log_subscriber"
|
3
|
-
|
4
|
-
class Tire::Rails::LogSubscriber
|
5
|
-
|
6
|
-
# better output format
|
7
|
-
def search(event)
|
8
|
-
self.class.runtime += event.duration
|
9
|
-
return unless logger.debug?
|
10
|
-
|
11
|
-
payload = event.payload
|
12
|
-
|
13
|
-
name = "%s (%.1fms)" % [payload[:name], event.duration]
|
14
|
-
query = payload[:search].to_s
|
15
|
-
|
16
|
-
debug " #{color(name, YELLOW, true)} #{query}"
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|