README.md in autosuggest-0.1.2 vs README.md in autosuggest-0.1.3

- old
+ new

@@ -83,23 +83,96 @@ ```ruby autosuggest.block_words ["boom"] ``` -#### Profit +#### Generate suggestions -Get suggestions with: +Generate suggestions with: ```ruby -autosuggest.suggestions(filter: true) +suggestions = autosuggest.suggestions(filter: true) ``` -Filter queries without results and you’re set. We also prefer to have someone manually approve them by hand. +#### Save suggestions -## Full Example +Save suggestions in your database or another data store. +With Rails, you can generate a simple model with: + +```sh +rails generate autosuggest:suggestions +rails db:migrate +``` + +And update suggestions with: + ```ruby +now = Time.now +records = suggestions.map { |s| s.slice(:query, :score).merge(updated_at: now) } +Autosuggest::Suggestion.transaction do + Autosuggest::Suggestion.upsert_all(records, unique_by: :query) + Autosuggest::Suggestion.where("updated_at < ?", now).delete_all +end +``` + +Leave out `unique_by` for MySQL, and use [activerecord-import](https://github.com/zdennis/activerecord-import) for upserts with Rails < 6. + +#### Show suggestions + +Use a JavaScript autocomplete library like [typeahead.js](https://github.com/twitter/typeahead.js) to show suggestions in the UI. + +If you only have a few thousand suggestions, it’s much faster to load them all at once instead of as a user types (eliminates network requests). + +With Rails, you can load all suggestions with: + +```ruby +Autosuggest::Suggestion.order(score: :desc).pluck(:query) +``` + +And suggestions matching user input with: + +```ruby +input = params[:query] +Autosuggest::Suggestion + .order(score: :desc) + .where("query LIKE ?", "%#{Autosuggest::Suggestion.sanitize_sql_like(input.downcase)}%") + .pluck(:query) +``` + +You can also cache suggestions for performance. + +```ruby +Rails.cache.fetch("suggestions", expires_in: 5.minutes) do + Autosuggest::Suggestion.order(score: :desc).pluck(:query) +end +``` + +#### Additional considerations + +You may want to have someone manually approve suggestions: + +```ruby +Autosuggest::Suggestion.where(approved: true) +``` + +Or filter suggestions without results: + +```ruby +Autosuggest::Suggestion.find_each do |suggestion| + suggestion.has_results = Product.search(suggestion.query, load: false, limit: 1).any? + suggestion.save! if suggestion.changed? +end + +Autosuggest::Suggestion.where(has_results: true) +``` + +You can add additional fields to your model/data store to accomplish this. + +## Example + +```ruby top_queries = Searchjoy::Search.group(:normalized_query) .having("COUNT(DISTINCT user_id) >= 5").distinct.count(:user_id) product_names = Product.pluck(:name) brand_names = Brand.pluck(:name) @@ -108,12 +181,17 @@ autosuggest.add_concept "brand", brand_names autosuggest.prefer brand_names autosuggest.not_duplicates [["straws", "straus"]] autosuggest.block_words ["boom"] -puts autosuggest.pretty_suggestions -# or suggestions = autosuggest.suggestions(filter: true) + +now = Time.now +records = suggestions.map { |s| s.slice(:query, :score).merge(updated_at: now) } +Autosuggest::Suggestion.transaction do + Autosuggest::Suggestion.upsert_all(records, unique_by: :query) + Autosuggest::Suggestion.where("updated_at < ?", now).delete_all +end ``` ## History View the [changelog](https://github.com/ankane/autosuggest/blob/master/CHANGELOG.md)