Commit 04000e0cdb96e1868e185d4dfd9177a7f23db861
1 parent
089ebf63
Exists in
master
and in
19 other branches
Added section on performant conversions [skip ci]
Showing
1 changed file
with
60 additions
and
1 deletions
Show diff stats
README.md
... | ... | @@ -543,7 +543,7 @@ Reindex and set up a cron job to add new conversions daily. |
543 | 543 | rake searchkick:reindex CLASS=Product |
544 | 544 | ``` |
545 | 545 | |
546 | -**Note:** For better performance, check out [this gist](https://gist.github.com/ankane/09af4746076112fc64f684fcb0d5b6da). | |
546 | +**Note:** For a more performant (but slightly more advanced) approach, check out [performant conversions](#performant-conversions). | |
547 | 547 | |
548 | 548 | ### Personalized Results |
549 | 549 | |
... | ... | @@ -1158,6 +1158,65 @@ Reindex and search with: |
1158 | 1158 | Business.search "ice cream", routing: params[:city_id] |
1159 | 1159 | ``` |
1160 | 1160 | |
1161 | +### Performant Conversions | |
1162 | + | |
1163 | +Split out conversions into a separate method so you can use partial reindexing, and cache conversions to prevent N+1 queries. | |
1164 | + | |
1165 | +```ruby | |
1166 | +class Product < ActiveRecord::Base | |
1167 | + def search_data | |
1168 | + { | |
1169 | + name: name | |
1170 | + }.merge(search_conversions) | |
1171 | + end | |
1172 | + | |
1173 | + def search_conversions | |
1174 | + { | |
1175 | + conversions: Rails.cache.read("search_conversions:#{self.class.name}:#{id}") || {} | |
1176 | + } | |
1177 | + end | |
1178 | +end | |
1179 | +``` | |
1180 | + | |
1181 | +Create a service to update the cache and reindex records with new conversions. | |
1182 | + | |
1183 | +```ruby | |
1184 | +class ReindexConversions | |
1185 | + def self.perform(model) | |
1186 | + class_name = model.name | |
1187 | + recently_converted_ids = | |
1188 | + Searchjoy::Search.where("convertable_type = ? AND converted_at > ?", class_name, 1.days.ago) | |
1189 | + .pluck(:convertable_id).sort | |
1190 | + | |
1191 | + recently_converted_ids.in_groups_of(1000, false) do |ids| | |
1192 | + # fetch conversions and group by record | |
1193 | + conversions_by_record = {} | |
1194 | + conversions = | |
1195 | + Searchjoy::Search.where(convertable_id: ids, convertable_type: class_name) | |
1196 | + .group(:convertable_id, :query).uniq.count(:user_id) | |
1197 | + | |
1198 | + conversions.each do |(id, query), count| | |
1199 | + (conversions_by_record[id] ||= {})[query] = count | |
1200 | + end | |
1201 | + | |
1202 | + # write to cache | |
1203 | + conversions_by_record.each do |id, conversions| | |
1204 | + Rails.cache.write("search_conversions:#{class_name}:#{id}", conversions) | |
1205 | + end | |
1206 | + | |
1207 | + # partial reindex | |
1208 | + class_name.constantize.where(id: ids).reindex(:search_conversions) | |
1209 | + end | |
1210 | + end | |
1211 | +end | |
1212 | +``` | |
1213 | + | |
1214 | +Use the service with: | |
1215 | + | |
1216 | +```ruby | |
1217 | +ReindexConversions.perform(Product) | |
1218 | +``` | |
1219 | + | |
1161 | 1220 | ## Large Data Sets |
1162 | 1221 | |
1163 | 1222 | ### Background Reindexing [experimental, ActiveRecord only] | ... | ... |