Commit 347326a2af5166256280f5151a3f07e2fc831d16

Authored by Andrew Kane
1 parent b83d8a0a

Added conversions and personalize options

@@ -16,9 +16,9 @@ Plus: @@ -16,9 +16,9 @@ Plus:
16 16
17 - query like SQL - no need to learn a new query language 17 - query like SQL - no need to learn a new query language
18 - reindex without downtime 18 - reindex without downtime
19 -- easily personalize results for each user [master branch]  
20 -- autocomplete [master branch]  
21 -- “Did you mean” suggestions [master branch] 19 +- easily personalize results for each user
  20 +- autocomplete
  21 +- “Did you mean” suggestions
22 22
23 :tangerine: Battle-tested at [Instacart](https://www.instacart.com) 23 :tangerine: Battle-tested at [Instacart](https://www.instacart.com)
24 24
@@ -132,20 +132,22 @@ To change this, use: @@ -132,20 +132,22 @@ To change this, use:
132 Product.search "fresh honey", partial: true # fresh OR honey 132 Product.search "fresh honey", partial: true # fresh OR honey
133 ``` 133 ```
134 134
135 -### Autocomplete [master branch] 135 +### Autocomplete
  136 +
  137 +![Autocomplete](http://ankane.github.io/searchkick/autocomplete.png)
136 138
137 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. 139 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.
138 140
139 ```ruby 141 ```ruby
140 -class Product < ActiveRecord::Base  
141 - searchkick autocomplete: [:name] 142 +class Website < ActiveRecord::Base
  143 + searchkick autocomplete: ["title"]
142 end 144 end
143 ``` 145 ```
144 146
145 Reindex and search with: 147 Reindex and search with:
146 148
147 ```ruby 149 ```ruby
148 -Product.search "puddi", autocomplete: true 150 +Website.search "where", autocomplete: true
149 ``` 151 ```
150 152
151 ### Synonyms 153 ### Synonyms
@@ -201,10 +203,14 @@ end @@ -201,10 +203,14 @@ end
201 203
202 Add conversions to the index. 204 Add conversions to the index.
203 205
  206 +**Note**: You must specify the conversions field as of version `0.2.0`.
  207 +
204 ```ruby 208 ```ruby
205 class Product < ActiveRecord::Base 209 class Product < ActiveRecord::Base
206 has_many :searches 210 has_many :searches
207 211
  212 + searchkick conversions: "conversions" # name of field
  213 +
208 def search_data 214 def search_data
209 { 215 {
210 name: name, 216 name: name,
@@ -221,14 +227,14 @@ Reindex and set up a cron job to add new conversions daily. @@ -221,14 +227,14 @@ Reindex and set up a cron job to add new conversions daily.
221 rake searchkick:reindex CLASS=Product 227 rake searchkick:reindex CLASS=Product
222 ``` 228 ```
223 229
224 -### Personalized Results [master branch]  
225 -  
226 -**Subject to change before the next gem release** 230 +### Personalized Results
227 231
228 -Order results differently for each user. For example, show a user’s previously ordered products before other results. 232 +Order results differently for each user. For example, show a user’s previously purchased products before other results.
229 233
230 ```ruby 234 ```ruby
231 class Product < ActiveRecord::Base 235 class Product < ActiveRecord::Base
  236 + searchkick personalize: "user_ids"
  237 +
232 def search_data 238 def search_data
233 { 239 {
234 name: name, 240 name: name,
@@ -245,13 +251,13 @@ Reindex and search with: @@ -245,13 +251,13 @@ Reindex and search with:
245 Product.search "milk", user_id: 8 251 Product.search "milk", user_id: 8
246 ``` 252 ```
247 253
248 -### Suggestions [master branch] 254 +### Suggestions
249 255
250 -Did you mean: awesome :sunglasses: 256 +![Suggest](http://ankane.github.io/searchkick/recursion.png)
251 257
252 ```ruby 258 ```ruby
253 class Product < ActiveRecord::Base 259 class Product < ActiveRecord::Base
254 - searchkick suggest: [:name] # fields to generate suggestions 260 + searchkick suggest: ["name"] # fields to generate suggestions
255 end 261 end
256 ``` 262 ```
257 263
lib/searchkick/model.rb
@@ -3,7 +3,6 @@ module Searchkick @@ -3,7 +3,6 @@ module Searchkick
3 3
4 def searchkick(options = {}) 4 def searchkick(options = {})
5 @searchkick_options = options.dup 5 @searchkick_options = options.dup
6 - @searchkick_options[:conversions] = true if options[:conversions].nil?  
7 6
8 class_eval do 7 class_eval do
9 extend Searchkick::Search 8 extend Searchkick::Search
@@ -31,8 +30,9 @@ module Searchkick @@ -31,8 +30,9 @@ module Searchkick
31 options = self.class.instance_variable_get("@searchkick_options") 30 options = self.class.instance_variable_get("@searchkick_options")
32 31
33 # conversions 32 # conversions
34 - if options[:conversions] and source["conversions"]  
35 - source["conversions"] = source["conversions"].map{|k, v| {query: k, count: v} } 33 + conversions_field = options[:conversions]
  34 + if conversions_field and source[conversions_field]
  35 + source[conversions_field] = source[conversions_field].map{|k, v| {query: k, count: v} }
36 end 36 end
37 37
38 # hack to prevent generator field doesn't exist error 38 # hack to prevent generator field doesn't exist error
lib/searchkick/search.rb
@@ -30,6 +30,9 @@ module Searchkick @@ -30,6 +30,9 @@ module Searchkick
30 offset = options[:offset] || (page && (page - 1) * per_page) 30 offset = options[:offset] || (page && (page - 1) * per_page)
31 index_name = options[:index_name] || index.name 31 index_name = options[:index_name] || index.name
32 32
  33 + conversions_field = @searchkick_options[:conversions]
  34 + personalize_field = @searchkick_options[:personalize]
  35 +
33 # TODO lose Tire DSL for more flexibility 36 # TODO lose Tire DSL for more flexibility
34 s = 37 s =
35 Tire::Search::Search.new do 38 Tire::Search::Search.new do
@@ -57,9 +60,9 @@ module Searchkick @@ -57,9 +60,9 @@ module Searchkick
57 end 60 end
58 end 61 end
59 end 62 end
60 - unless options[:conversions] == false 63 + if conversions_field and options[:conversions] != false
61 should do 64 should do
62 - nested path: "conversions", score_mode: "total" do 65 + nested path: conversions_field, score_mode: "total" do
63 query do 66 query do
64 custom_score script: "doc['count'].value" do 67 custom_score script: "doc['count'].value" do
65 match "query", term 68 match "query", term
@@ -76,9 +79,9 @@ module Searchkick @@ -76,9 +79,9 @@ module Searchkick
76 script "log(doc['#{options[:boost]}'].value + 2.718281828)" 79 script "log(doc['#{options[:boost]}'].value + 2.718281828)"
77 end 80 end
78 end 81 end
79 - if options[:user_id] 82 + if options[:user_id] and personalize_field
80 filter do 83 filter do
81 - filter :term, user_ids: options[:user_id] 84 + filter :term, personalize_field => options[:user_id]
82 boost 100 85 boost 100
83 end 86 end
84 end 87 end
test/test_helper.rb
@@ -49,7 +49,9 @@ class Product &lt; ActiveRecord::Base @@ -49,7 +49,9 @@ class Product &lt; ActiveRecord::Base
49 ["bandaid", "bandag"] 49 ["bandaid", "bandag"]
50 ], 50 ],
51 autocomplete: [:name], 51 autocomplete: [:name],
52 - suggest: [:name, :color] 52 + suggest: [:name, :color],
  53 + conversions: "conversions",
  54 + personalize: "user_ids"
53 55
54 attr_accessor :conversions, :user_ids 56 attr_accessor :conversions, :user_ids
55 57