searchkick 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|