searchkick 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 275937983ec78c77a0d7f25fa26a9fbe067a5154
4
- data.tar.gz: 31783a30cf0b0d6170d94a99daf2c0022d20008d
3
+ metadata.gz: f7e8d412864f6c87ba170611a9b2cdfb6d6f6cc8
4
+ data.tar.gz: 98d9385aa9ad6c967ccdae9924f15d8bf0c1ee69
5
5
  SHA512:
6
- metadata.gz: 636392d9b685813dbdcfd6d8b9f9aa715be73515e089f32a1c95a870c3c0ff17a3a336c3605318b9f8ea6ca406927493752fa6d603762f70a77777de41306144
7
- data.tar.gz: 954203fe3c5a0e48d404322c7a270cde965bbd5f69e32e285da9e1582546cd5257bd87b616315c3e997db9402838f4966920fd5c0e10c195502b0b54214a64ff
6
+ metadata.gz: 00cfd0a2da2ce78127466636d5176c89356ef90311335b26f0050d58375cd3eb082113255a7eb3c71a5e0860e5c2b45a0a463363d1665e8e765ce14bb0d4d371
7
+ data.tar.gz: a90e126bfe9c460538ef89570e1da4512b93c804b45d43b01384c0bd5cb29d128db88668c3fa2fd009dcdc5abd4870f9216b6b6b3f4f580833703c42709e5d35
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.2.4
2
+
3
+ - Use `to_hash` instead of `as_json` for default `search_data` method
4
+ - Works for Mongoid 1.3
5
+ - Use one shard in test environment for consistent scores
6
+
1
7
  ## 0.2.3
2
8
 
3
9
  - Setup Travis
data/Gemfile CHANGED
@@ -2,3 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in searchkick.gemspec
4
4
  gemspec
5
+
6
+ # gem "mongoid", github: "mongoid/mongoid"
7
+ # gem "mongoid", "~> 3.1.0"
8
+ # gem "activerecord", "~> 3.2.0"
9
+ # gem "activerecord", "~> 3.1.0"
data/README.md CHANGED
@@ -19,6 +19,7 @@ Plus:
19
19
  - easily personalize results for each user
20
20
  - autocomplete
21
21
  - “Did you mean” suggestions
22
+ - works with ActiveRecord and Mongoid
22
23
 
23
24
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com)
24
25
 
@@ -134,24 +135,6 @@ To change this, use:
134
135
  Product.search "fresh honey", partial: true # fresh OR honey
135
136
  ```
136
137
 
137
- ### Autocomplete
138
-
139
- ![Autocomplete](http://ankane.github.io/searchkick/autocomplete.png)
140
-
141
- You must specify which fields use this feature since this can increase the index size significantly. Don’t worry - this gives you blazing faster queries.
142
-
143
- ```ruby
144
- class Website < ActiveRecord::Base
145
- searchkick autocomplete: ["title"]
146
- end
147
- ```
148
-
149
- Reindex and search with:
150
-
151
- ```ruby
152
- Website.search "where", autocomplete: true
153
- ```
154
-
155
138
  ### Synonyms
156
139
 
157
140
  ```ruby
@@ -187,6 +170,19 @@ class Product < ActiveRecord::Base
187
170
  end
188
171
  ```
189
172
 
173
+ ### To Reindex, or Not to Reindex
174
+
175
+ #### Reindex
176
+
177
+ - when you install or upgrade searchkick
178
+ - change the `search_data` method
179
+ - change the `searchkick` method
180
+
181
+ #### No need to reindex
182
+
183
+ - App starts
184
+ - Records are inserted, updated or deleted (syncs automatically)
185
+
190
186
  ### Keep Getting Better
191
187
 
192
188
  Searchkick uses conversion data to learn what users are looking for. If a user searches for “ice cream” and adds Ben & Jerry’s Chunky Monkey to the cart (our conversion metric at Instacart), that item gets a little more weight for similar searches.
@@ -250,6 +246,58 @@ Reindex and search with:
250
246
  Product.search "milk", user_id: 8
251
247
  ```
252
248
 
249
+ ### Autocomplete
250
+
251
+ Autocomplete predicts what a user will type, making the search experience faster and easier.
252
+
253
+ ![Autocomplete](http://ankane.github.io/searchkick/autocomplete.png)
254
+
255
+ First, specify which fields use this feature. This is necessary since autocomplete can increase the index size significantly, but don’t worry - this gives you blazing faster queries.
256
+
257
+ ```ruby
258
+ class City < ActiveRecord::Base
259
+ searchkick autocomplete: ["name"]
260
+ end
261
+ ```
262
+
263
+ Reindex and search with:
264
+
265
+ ```ruby
266
+ City.search "san fr", autocomplete: true
267
+ ```
268
+
269
+ Typically, you want to use a Javascript library like [typeahead.js](http://twitter.github.io/typeahead.js/) or [jQuery UI](http://jqueryui.com/autocomplete/).
270
+
271
+ #### Here’s how to make it work with Rails
272
+
273
+ First, add a controller action.
274
+
275
+ ```ruby
276
+ # app/controllers/cities_controller.rb
277
+ class CitiesController < ApplicationController
278
+
279
+ def autocomplete
280
+ render json: City.search(params[:q], autocomplete: true, limit: 10).map(&:name)
281
+ end
282
+
283
+ end
284
+ ```
285
+
286
+ Then add the search box and Javascript code to a view.
287
+
288
+ ```html
289
+ <input type="text" id="q" name="q" />
290
+
291
+ <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
292
+ <script src="//cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.9.3/typeahead.min.js"></script>
293
+ <script>
294
+ $("#q").typeahead({
295
+ name: "city",
296
+ remote: "/cities/autocomplete?q=%QUERY"
297
+ });
298
+ </script>
299
+ ```
300
+
253
301
  ### Suggestions
254
302
 
255
303
  ![Suggest](http://ankane.github.io/searchkick/recursion.png)
data/lib/searchkick.rb CHANGED
@@ -9,5 +9,5 @@ require "searchkick/tasks"
9
9
  require "searchkick/logger" if defined?(Rails)
10
10
 
11
11
  # TODO find better ActiveModel hook
12
- ActiveModel::AttributeMethods::ClassMethods.send(:include, Searchkick::Model)
12
+ ActiveModel::Callbacks.send(:include, Searchkick::Model)
13
13
  ActiveRecord::Base.send(:extend, Searchkick::Model) if defined?(ActiveRecord)
@@ -19,7 +19,7 @@ module Searchkick
19
19
  end
20
20
 
21
21
  def search_data
22
- as_json
22
+ to_hash.reject{|k, v| k == "id" }
23
23
  end
24
24
 
25
25
  def to_indexed_json
@@ -14,8 +14,22 @@ module Searchkick
14
14
 
15
15
  # use scope for import
16
16
  scope = respond_to?(:search_import) ? search_import : self
17
- scope.find_in_batches do |batch|
18
- index.import batch
17
+ if scope.respond_to?(:find_in_batches)
18
+ scope.find_in_batches do |batch|
19
+ index.import batch
20
+ end
21
+ else
22
+ # https://github.com/karmi/tire/blob/master/lib/tire/model/import.rb
23
+ # use cursor for Mongoid
24
+ items = []
25
+ scope.all.each do |item|
26
+ items << item
27
+ if items.length % 1000 == 0
28
+ index.import items
29
+ items = []
30
+ end
31
+ end
32
+ index.import items
19
33
  end
20
34
 
21
35
  if a = Tire::Alias.find(alias_name)
@@ -121,7 +135,13 @@ module Searchkick
121
135
  }
122
136
  }
123
137
  }
124
- }.merge(options[:settings] || {})
138
+ }
139
+
140
+ if ENV["RACK_ENV"] == "test"
141
+ settings.merge!(number_of_shards: 1, number_of_replicas: 0)
142
+ end
143
+
144
+ settings.merge!(options[:settings] || {})
125
145
 
126
146
  # synonyms
127
147
  synonyms = options[:synonyms] || []
@@ -28,7 +28,7 @@ module Searchkick
28
28
  page = [options[:page].to_i, 1].max
29
29
  per_page = options[:limit] || options[:per_page] || 100000
30
30
  offset = options[:offset] || (page - 1) * per_page
31
- index_name = options[:index_name] || index.name
31
+ index_name = options[:index_name] || tire.index.name
32
32
 
33
33
  conversions_field = @searchkick_options[:conversions]
34
34
  personalize_field = @searchkick_options[:personalize]
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
data/test/index_test.rb CHANGED
@@ -12,7 +12,7 @@ class TestIndex < Minitest::Unit::TestCase
12
12
 
13
13
  Product.clean_indices
14
14
 
15
- assert Product.index.exists?
15
+ assert Product.tire.index.exists?
16
16
  assert different_index.exists?
17
17
  assert !old_index.exists?
18
18
  end
data/test/similar_test.rb CHANGED
@@ -4,7 +4,7 @@ class TestSimilar < Minitest::Unit::TestCase
4
4
 
5
5
  def test_fields
6
6
  store_names ["1% Organic Milk", "2% Organic Milk", "Popcorn"]
7
- assert_equal ["2% Organic Milk"], Product.find_by(name: "1% Organic Milk").similar(fields: ["name"]).map(&:name)
7
+ assert_equal ["2% Organic Milk"], Product.where(name: "1% Organic Milk").first.similar(fields: ["name"]).map(&:name)
8
8
  end
9
9
 
10
10
  end
data/test/test_helper.rb CHANGED
@@ -2,47 +2,65 @@ require "bundler/setup"
2
2
  Bundler.require(:default)
3
3
  require "minitest/autorun"
4
4
  require "minitest/pride"
5
- require "active_record"
6
5
 
7
6
  ENV["RACK_ENV"] = "test"
8
7
 
9
- # for debugging
10
- # ActiveRecord::Base.logger = Logger.new(STDOUT)
8
+ File.delete("elasticsearch.log") if File.exists?("elasticsearch.log")
9
+ Tire.configure do
10
+ logger "elasticsearch.log", :level => "debug"
11
+ pretty true
12
+ end
11
13
 
12
- # rails does this in activerecord/lib/active_record/railtie.rb
13
- ActiveRecord::Base.default_timezone = :utc
14
- ActiveRecord::Base.time_zone_aware_attributes = true
14
+ if ENV["MONGOID"]
15
+ Mongoid.configure do |config|
16
+ config.connect_to "searchkick_test"
17
+ end
15
18
 
16
- # migrations
17
- ActiveRecord::Base.establish_connection :adapter => "postgresql", :database => "searchkick_test"
19
+ class Product
20
+ include Mongoid::Document
21
+ # include Mongoid::Attributes::Dynamic
22
+ end
18
23
 
19
- ActiveRecord::Migration.create_table :products, :force => true do |t|
20
- t.string :name
21
- t.integer :store_id
22
- t.boolean :in_stock
23
- t.boolean :backordered
24
- t.integer :orders_count
25
- t.string :color
26
- t.timestamps
27
- end
24
+ class Store
25
+ include Mongoid::Document
26
+ end
27
+ else
28
+ require "active_record"
29
+
30
+ # for debugging
31
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
32
+
33
+ # rails does this in activerecord/lib/active_record/railtie.rb
34
+ ActiveRecord::Base.default_timezone = :utc
35
+ ActiveRecord::Base.time_zone_aware_attributes = true
36
+
37
+ # migrations
38
+ ActiveRecord::Base.establish_connection :adapter => "postgresql", :database => "searchkick_test"
39
+
40
+ ActiveRecord::Migration.create_table :products, :force => true do |t|
41
+ t.string :name
42
+ t.integer :store_id
43
+ t.boolean :in_stock
44
+ t.boolean :backordered
45
+ t.integer :orders_count
46
+ t.string :color
47
+ t.timestamps
48
+ end
28
49
 
29
- ActiveRecord::Migration.create_table :store, :force => true do |t|
30
- end
50
+ ActiveRecord::Migration.create_table :store, :force => true do |t|
51
+ end
31
52
 
32
- File.delete("elasticsearch.log") if File.exists?("elasticsearch.log")
33
- Tire.configure do
34
- logger "elasticsearch.log", :level => "debug"
35
- pretty true
53
+ class Product < ActiveRecord::Base
54
+ end
55
+
56
+ class Store < ActiveRecord::Base
57
+ end
36
58
  end
37
59
 
38
- class Product < ActiveRecord::Base
60
+ class Product
39
61
  belongs_to :store
40
62
 
41
63
  searchkick \
42
- settings: {
43
- number_of_shards: 1,
44
- number_of_replicas: 0
45
- },
46
64
  synonyms: [
47
65
  ["clorox", "bleach"],
48
66
  ["scallion", "greenonion"],
@@ -59,14 +77,11 @@ class Product < ActiveRecord::Base
59
77
  attr_accessor :conversions, :user_ids
60
78
 
61
79
  def search_data
62
- as_json.merge conversions: conversions, user_ids: user_ids
80
+ to_hash.merge conversions: conversions, user_ids: user_ids
63
81
  end
64
82
  end
65
83
 
66
- class Store < ActiveRecord::Base
67
- end
68
-
69
- Product.index.delete if Product.index.exists?
84
+ Product.tire.index.delete if Product.tire.index.exists?
70
85
  Product.reindex
71
86
  Product.reindex # run twice for both index paths
72
87
 
@@ -82,7 +97,7 @@ class MiniTest::Unit::TestCase
82
97
  documents.shuffle.each do |document|
83
98
  Product.create!(document)
84
99
  end
85
- Product.index.refresh
100
+ Product.tire.index.refresh
86
101
  end
87
102
 
88
103
  def store_names(names)
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.2.3
4
+ version: 0.2.4
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-08-16 00:00:00.000000000 Z
11
+ date: 2013-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tire