searchkick 0.3.1 → 0.3.2
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 +5 -0
- data/README.md +24 -1
- data/lib/searchkick/model.rb +37 -13
- data/lib/searchkick/reindex.rb +8 -7
- data/lib/searchkick/search.rb +11 -9
- data/lib/searchkick/similar.rb +1 -1
- data/lib/searchkick/version.rb +1 -1
- data/test/index_test.rb +1 -1
- data/test/inheritance_test.rb +33 -0
- data/test/test_helper.rb +38 -8
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff1b17b6561440bad2ebe3c20d1606b13d579310
|
4
|
+
data.tar.gz: 50475abfd988e11bca0b04385a4ec264bac80467
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19e25e2f81fb811f7bf1964cb59a5deccfc6386d10640279bfe6cfb7bb81a1611691ebd6ccb8879c7dcbec4f530d5ccf2fae089e19cc8f783409985092d2315b
|
7
|
+
data.tar.gz: be76d99160e570515a3120ecb517a6faef29f2b3b95eb4ebc6556cbe2839d3554faa7295ff72ccc14caf82fb817b65e2286a74377fd95137d68c6666383bc26f
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -360,7 +360,7 @@ class City < ActiveRecord::Base
|
|
360
360
|
searchkick locations: ["location"]
|
361
361
|
|
362
362
|
def search_data
|
363
|
-
to_hash.merge location: [latitude
|
363
|
+
to_hash.merge location: [latitude, longitude]
|
364
364
|
end
|
365
365
|
end
|
366
366
|
```
|
@@ -419,6 +419,29 @@ Then deploy and reindex:
|
|
419
419
|
rake searchkick:reindex CLASS=Product
|
420
420
|
```
|
421
421
|
|
422
|
+
## Inheritance
|
423
|
+
|
424
|
+
Searchkick supports single table inheritance.
|
425
|
+
|
426
|
+
```ruby
|
427
|
+
class Dog < Animal
|
428
|
+
end
|
429
|
+
```
|
430
|
+
|
431
|
+
The parent and child model can both reindex.
|
432
|
+
|
433
|
+
```ruby
|
434
|
+
Animal.reindex
|
435
|
+
Dog.reindex # equivalent
|
436
|
+
```
|
437
|
+
|
438
|
+
And to search, use:
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
Animal.search "*" # all animals
|
442
|
+
Dog.search "*" # just dogs
|
443
|
+
```
|
444
|
+
|
422
445
|
## Reference
|
423
446
|
|
424
447
|
Searchkick requires Elasticsearch `0.90.0` or higher.
|
data/lib/searchkick/model.rb
CHANGED
@@ -2,26 +2,39 @@ module Searchkick
|
|
2
2
|
module Model
|
3
3
|
|
4
4
|
def searchkick(options = {})
|
5
|
-
@searchkick_options = options.dup
|
6
|
-
@searchkick_env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
|
7
|
-
searchkick_env = @searchkick_env # for class_eval
|
8
|
-
|
9
5
|
class_eval do
|
6
|
+
cattr_reader :searchkick_options, :searchkick_env, :searchkick_klass, :searchkick_index
|
7
|
+
|
8
|
+
class_variable_set :@@searchkick_options, options.dup
|
9
|
+
class_variable_set :@@searchkick_env, ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
|
10
|
+
class_variable_set :@@searchkick_klass, self
|
11
|
+
|
12
|
+
# set index name
|
13
|
+
# TODO support proc
|
14
|
+
index_name = options[:index_name] || [options[:index_prefix], model_name.plural, searchkick_env].compact.join("_")
|
15
|
+
class_variable_set :@@searchkick_index, Tire::Index.new(index_name)
|
16
|
+
|
10
17
|
extend Searchkick::Search
|
11
18
|
extend Searchkick::Reindex
|
12
19
|
include Searchkick::Similar
|
13
|
-
include Tire::Model::Search
|
14
|
-
include Tire::Model::Callbacks unless options[:callbacks] == false
|
15
|
-
tire do
|
16
|
-
index_name options[:index_name] || [options[:index_prefix], klass.model_name.plural, searchkick_env].compact.join("_")
|
17
|
-
end
|
18
20
|
|
19
21
|
def reindex
|
20
|
-
|
22
|
+
index = self.class.searchkick_index
|
23
|
+
if destroyed?
|
24
|
+
index.remove self
|
25
|
+
else
|
26
|
+
index.store self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
unless options[:callbacks] == false
|
31
|
+
# TODO ability to temporarily disable
|
32
|
+
after_save :reindex
|
33
|
+
after_destroy :reindex
|
21
34
|
end
|
22
35
|
|
23
36
|
def search_data
|
24
|
-
to_hash
|
37
|
+
respond_to?(:to_hash) ? to_hash : serializable_hash
|
25
38
|
end
|
26
39
|
|
27
40
|
def to_indexed_json
|
@@ -30,7 +43,7 @@ module Searchkick
|
|
30
43
|
# stringify fields
|
31
44
|
source = source.inject({}){|memo,(k,v)| memo[k.to_s] = v; memo}
|
32
45
|
|
33
|
-
options = self.class.
|
46
|
+
options = self.class.searchkick_options
|
34
47
|
|
35
48
|
# conversions
|
36
49
|
conversions_field = options[:conversions]
|
@@ -45,11 +58,22 @@ module Searchkick
|
|
45
58
|
|
46
59
|
# locations
|
47
60
|
(options[:locations] || []).map(&:to_s).each do |field|
|
48
|
-
source[field] = source[field].reverse if source[field]
|
61
|
+
source[field] = source[field].map(&:to_f).reverse if source[field]
|
49
62
|
end
|
50
63
|
|
51
64
|
source.to_json
|
52
65
|
end
|
66
|
+
|
67
|
+
# TODO remove
|
68
|
+
|
69
|
+
def self.document_type
|
70
|
+
model_name.to_s.underscore
|
71
|
+
end
|
72
|
+
|
73
|
+
def document_type
|
74
|
+
self.class.document_type
|
75
|
+
end
|
76
|
+
|
53
77
|
end
|
54
78
|
end
|
55
79
|
|
data/lib/searchkick/reindex.rb
CHANGED
@@ -3,7 +3,7 @@ module Searchkick
|
|
3
3
|
|
4
4
|
# https://gist.github.com/jarosan/3124884
|
5
5
|
def reindex
|
6
|
-
alias_name =
|
6
|
+
alias_name = searchkick_index.name
|
7
7
|
new_index = alias_name + "_" + Time.now.strftime("%Y%m%d%H%M%S%L")
|
8
8
|
index = Tire::Index.new(new_index)
|
9
9
|
|
@@ -28,7 +28,7 @@ module Searchkick
|
|
28
28
|
raise response.to_s
|
29
29
|
end
|
30
30
|
else
|
31
|
-
|
31
|
+
searchkick_index.delete if searchkick_index.exists?
|
32
32
|
response = Tire::Alias.create(name: alias_name, indices: [new_index])
|
33
33
|
raise response.to_s if !response.success?
|
34
34
|
|
@@ -41,7 +41,7 @@ module Searchkick
|
|
41
41
|
# remove old indices that start w/ index_name
|
42
42
|
def clean_indices
|
43
43
|
all_indices = JSON.parse(Tire::Configuration.client.get("#{Tire::Configuration.url}/_aliases").body)
|
44
|
-
indices = all_indices.select{|k, v| v["aliases"].empty? && k =~ /\A#{Regexp.escape(
|
44
|
+
indices = all_indices.select{|k, v| v["aliases"].empty? && k =~ /\A#{Regexp.escape(searchkick_index.name)}_\d{14,17}\z/ }.keys
|
45
45
|
indices.each do |index|
|
46
46
|
Tire::Index.new(index).delete
|
47
47
|
end
|
@@ -56,7 +56,8 @@ module Searchkick
|
|
56
56
|
|
57
57
|
def searchkick_import(index)
|
58
58
|
# use scope for import
|
59
|
-
scope =
|
59
|
+
scope = searchkick_klass
|
60
|
+
scope = scope.search_import if scope.respond_to?(:search_import)
|
60
61
|
if scope.respond_to?(:find_in_batches)
|
61
62
|
scope.find_in_batches do |batch|
|
62
63
|
index.import batch
|
@@ -77,7 +78,7 @@ module Searchkick
|
|
77
78
|
end
|
78
79
|
|
79
80
|
def searchkick_index_options
|
80
|
-
options =
|
81
|
+
options = searchkick_options
|
81
82
|
|
82
83
|
settings = {
|
83
84
|
analysis: {
|
@@ -148,7 +149,7 @@ module Searchkick
|
|
148
149
|
}
|
149
150
|
}
|
150
151
|
|
151
|
-
if
|
152
|
+
if searchkick_env == "test"
|
152
153
|
settings.merge!(number_of_shards: 1, number_of_replicas: 0)
|
153
154
|
end
|
154
155
|
|
@@ -220,7 +221,7 @@ module Searchkick
|
|
220
221
|
end
|
221
222
|
|
222
223
|
mappings = {
|
223
|
-
document_type.to_sym => {
|
224
|
+
searchkick_klass.document_type.to_sym => {
|
224
225
|
properties: mapping,
|
225
226
|
# https://gist.github.com/kimchy/2898285
|
226
227
|
dynamic_templates: [
|
data/lib/searchkick/search.rb
CHANGED
@@ -12,7 +12,7 @@ module Searchkick
|
|
12
12
|
end
|
13
13
|
else
|
14
14
|
if options[:autocomplete]
|
15
|
-
(
|
15
|
+
(searchkick_options[:autocomplete] || []).map{|f| "#{f}.autocomplete" }
|
16
16
|
else
|
17
17
|
["_all"]
|
18
18
|
end
|
@@ -28,10 +28,10 @@ module Searchkick
|
|
28
28
|
page = [options[:page].to_i, 1].max
|
29
29
|
per_page = (options[:limit] || options[:per_page] || 100000).to_i
|
30
30
|
offset = options[:offset] || (page - 1) * per_page
|
31
|
-
index_name = options[:index_name] ||
|
31
|
+
index_name = options[:index_name] || searchkick_index.name
|
32
32
|
|
33
|
-
conversions_field =
|
34
|
-
personalize_field =
|
33
|
+
conversions_field = searchkick_options[:conversions]
|
34
|
+
personalize_field = searchkick_options[:personalize]
|
35
35
|
|
36
36
|
all = term == "*"
|
37
37
|
|
@@ -176,7 +176,7 @@ module Searchkick
|
|
176
176
|
if value[:near]
|
177
177
|
filters << {
|
178
178
|
geo_distance: {
|
179
|
-
field => value.delete(:near).reverse,
|
179
|
+
field => value.delete(:near).map(&:to_f).reverse,
|
180
180
|
distance: value.delete(:within) || "50mi"
|
181
181
|
}
|
182
182
|
}
|
@@ -186,8 +186,8 @@ module Searchkick
|
|
186
186
|
filters << {
|
187
187
|
geo_bounding_box: {
|
188
188
|
field => {
|
189
|
-
top_left: value.delete(:top_left).reverse,
|
190
|
-
bottom_right: value.delete(:bottom_right).reverse
|
189
|
+
top_left: value.delete(:top_left).map(&:to_f).reverse,
|
190
|
+
bottom_right: value.delete(:bottom_right).map(&:to_f).reverse
|
191
191
|
}
|
192
192
|
}
|
193
193
|
}
|
@@ -269,7 +269,7 @@ module Searchkick
|
|
269
269
|
|
270
270
|
# suggestions
|
271
271
|
if options[:suggest]
|
272
|
-
suggest_fields = (
|
272
|
+
suggest_fields = (searchkick_options[:suggest] || []).map(&:to_s)
|
273
273
|
# intersection
|
274
274
|
suggest_fields = suggest_fields & options[:fields].map(&:to_s) if options[:fields]
|
275
275
|
if suggest_fields.any?
|
@@ -288,7 +288,9 @@ module Searchkick
|
|
288
288
|
# http://www.elasticsearch.org/guide/reference/api/search/fields/
|
289
289
|
payload[:fields] = [] if load
|
290
290
|
|
291
|
-
|
291
|
+
tire_options = {load: load, payload: payload, size: per_page, from: offset}
|
292
|
+
tire_options[:type] = document_type if self != searchkick_klass
|
293
|
+
search = Tire::Search::Search.new(index_name, tire_options)
|
292
294
|
response = search.json
|
293
295
|
|
294
296
|
# apply facet limit in client due to
|
data/lib/searchkick/similar.rb
CHANGED
@@ -2,7 +2,7 @@ module Searchkick
|
|
2
2
|
module Similar
|
3
3
|
|
4
4
|
def similar(options = {})
|
5
|
-
like_text =
|
5
|
+
like_text = self.class.searchkick_index.retrieve(document_type, id).to_hash
|
6
6
|
.keep_if{|k,v| k[0] != "_" and (!options[:fields] or options[:fields].map(&:to_sym).include?(k)) }
|
7
7
|
.values.compact.join(" ")
|
8
8
|
|
data/lib/searchkick/version.rb
CHANGED
data/test/index_test.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class TestInheritance < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
Animal.destroy_all
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_child_reindex
|
11
|
+
store_names ["Max"], Cat
|
12
|
+
assert Dog.reindex
|
13
|
+
Animal.searchkick_index.refresh
|
14
|
+
assert_equal 1, Animal.search("*").size
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_child_index_name
|
18
|
+
assert_equal "animals_test", Dog.searchkick_index.name
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_child_search
|
22
|
+
store_names ["Bear"], Dog
|
23
|
+
store_names ["Bear"], Cat
|
24
|
+
assert_equal 1, Dog.search("bear").size
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_parent_search
|
28
|
+
store_names ["Bear"], Dog
|
29
|
+
store_names ["Bear"], Cat
|
30
|
+
assert_equal 2, Animal.search("bear").size
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -24,6 +24,16 @@ if ENV["MONGOID"]
|
|
24
24
|
class Store
|
25
25
|
include Mongoid::Document
|
26
26
|
end
|
27
|
+
|
28
|
+
class Animal
|
29
|
+
include Mongoid::Document
|
30
|
+
end
|
31
|
+
|
32
|
+
class Dog < Animal
|
33
|
+
end
|
34
|
+
|
35
|
+
class Cat < Animal
|
36
|
+
end
|
27
37
|
else
|
28
38
|
require "active_record"
|
29
39
|
|
@@ -49,7 +59,12 @@ else
|
|
49
59
|
t.timestamps
|
50
60
|
end
|
51
61
|
|
52
|
-
ActiveRecord::Migration.create_table :
|
62
|
+
ActiveRecord::Migration.create_table :stores, :force => true do |t|
|
63
|
+
end
|
64
|
+
|
65
|
+
ActiveRecord::Migration.create_table :animals, :force => true do |t|
|
66
|
+
t.string :name
|
67
|
+
t.string :type
|
53
68
|
end
|
54
69
|
|
55
70
|
class Product < ActiveRecord::Base
|
@@ -57,6 +72,15 @@ else
|
|
57
72
|
|
58
73
|
class Store < ActiveRecord::Base
|
59
74
|
end
|
75
|
+
|
76
|
+
class Animal < ActiveRecord::Base
|
77
|
+
end
|
78
|
+
|
79
|
+
class Dog < Animal
|
80
|
+
end
|
81
|
+
|
82
|
+
class Cat < Animal
|
83
|
+
end
|
60
84
|
end
|
61
85
|
|
62
86
|
class Product
|
@@ -80,14 +104,20 @@ class Product
|
|
80
104
|
attr_accessor :conversions, :user_ids
|
81
105
|
|
82
106
|
def search_data
|
83
|
-
|
107
|
+
attributes.merge conversions: conversions, user_ids: user_ids, location: [latitude, longitude]
|
84
108
|
end
|
85
109
|
end
|
86
110
|
|
87
|
-
|
111
|
+
class Animal
|
112
|
+
searchkick
|
113
|
+
end
|
114
|
+
|
115
|
+
Product.searchkick_index.delete if Product.searchkick_index.exists?
|
88
116
|
Product.reindex
|
89
117
|
Product.reindex # run twice for both index paths
|
90
118
|
|
119
|
+
Animal.reindex
|
120
|
+
|
91
121
|
class MiniTest::Unit::TestCase
|
92
122
|
|
93
123
|
def setup
|
@@ -96,15 +126,15 @@ class MiniTest::Unit::TestCase
|
|
96
126
|
|
97
127
|
protected
|
98
128
|
|
99
|
-
def store(documents)
|
129
|
+
def store(documents, klass = Product)
|
100
130
|
documents.shuffle.each do |document|
|
101
|
-
|
131
|
+
klass.create!(document)
|
102
132
|
end
|
103
|
-
|
133
|
+
klass.searchkick_index.refresh
|
104
134
|
end
|
105
135
|
|
106
|
-
def store_names(names)
|
107
|
-
store names.map{|name| {name: name} }
|
136
|
+
def store_names(names, klass = Product)
|
137
|
+
store names.map{|name| {name: name} }, klass
|
108
138
|
end
|
109
139
|
|
110
140
|
# no order
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: searchkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tire
|
@@ -136,6 +136,7 @@ files:
|
|
136
136
|
- test/boost_test.rb
|
137
137
|
- test/facets_test.rb
|
138
138
|
- test/index_test.rb
|
139
|
+
- test/inheritance_test.rb
|
139
140
|
- test/match_test.rb
|
140
141
|
- test/similar_test.rb
|
141
142
|
- test/sql_test.rb
|
@@ -171,6 +172,7 @@ test_files:
|
|
171
172
|
- test/boost_test.rb
|
172
173
|
- test/facets_test.rb
|
173
174
|
- test/index_test.rb
|
175
|
+
- test/inheritance_test.rb
|
174
176
|
- test/match_test.rb
|
175
177
|
- test/similar_test.rb
|
176
178
|
- test/sql_test.rb
|