Autocomplete suggestions based on what your users search
Switch branches/tags
Nothing to show
Clone or download
Latest commit e93de61 Jul 19, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib Use https url [skip ci] Jul 19, 2018
test First commit Jun 20, 2015
.gitignore First commit Jun 20, 2015
Gemfile First commit Jun 20, 2015
README.md Simplified example Jun 21, 2015
Rakefile First commit Jun 20, 2015
autosuggest.gemspec First commit Jun 20, 2015

README.md

Autosuggest

Generate autocomplete suggestions based on what your users search

🍊 Battle-tested at Instacart

How It Works

Start with the most popular queries

top_queries = Search.group("LOWER(query)")
                    .having("COUNT(DISTINCT user_id) >= 5")
                    .count("DISTINCT user_id")
# {"bananas" => 353, "apples" => 213, ...

autosuggest = Autosuggest.new(top_queries)

Filter duplicates

Stemming is used to detect duplicates like apple and apples.

The most popular query is preferred by default. To override this, use:

autosuggest.prefer ["apples"]

To fix false positives, use:

autosuggest.not_duplicates [["straws", "straus"]]

Filter misspellings

We tried open-source libraries like Aspell and Hunspell but quickly realized we needed to build a corpus specific to our application.

There are two ways to build the corpus, which can be used together.

  1. Add words
autosuggest.parse_words Product.pluck(:name)

Use the min option to only add words that appear multiple times.

  1. Add concepts
autosuggest.add_concept "brand", Brand.pluck(:name)

Blacklist words

Profanity is blacklisted by default.

Add custom words with:

autosuggest.blacklist_words ["boom"]

Profit

Get suggestions with:

autosuggest.suggestions

Filter queries without results and you’re set.

We also prefer to have someone manually approve them by hand.

Full Example

top_queries = Search.group("LOWER(query)")
                    .having("COUNT(DISTINCT user_id) >= 5")
                    .count("DISTINCT user_id")
product_names = Product.pluck(:name)
brand_names = Brand.pluck(:name)

autosuggest = Autosuggest.new(top_queries)
autosuggest.parse_words product_names
autosuggest.add_concept "brand", brand_names
autosuggest.prefer brand_names
autosuggest.not_duplicates [["straws", "straus"]]
autosuggest.blacklist_words ["boom"]

puts autosuggest.pretty_suggestions
# or
suggestions = autosuggest.suggestions

Installation

Add this line to your application’s Gemfile:

gem 'autosuggest'

TODO

  • try Jaro-Winkler for duplicates

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help: