ankane / searchjoy

Search analytics made easy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool


Search analytics made easy

See it in action


  • view searches in real-time
  • track conversion rate week over week
  • monitor the performance of top searches

Works with any search platform, including Elasticsearch, OpenSearch, Sphinx, and Solr

💘 An amazing companion to Searchkick

Build Status


Add this line to your application’s Gemfile:

gem "searchjoy"

And run the generator. This creates a migration to store searches.

rails generate searchjoy:install
rails db:migrate

Next, add the dashboard to your config/routes.rb.

mount Searchjoy::Engine, at: "searchjoy"

Be sure to protect the endpoint in production - see the Authentication section for ways to do this.

Track Searches

Track searches by creating a record in the database.

  search_type: "Item", # typically the model name
  query: "apple",
  results_count: 12,
  user_id: 1

With Searchkick, you can use the track option to do this automatically."apple", track: {user_id: 1})

If you want to track more attributes, add them to the searchjoy_searches table.

add_column :searchjoy_searches, :source, :string

Then, pass the values to the track option."apple", track: {user_id: 1, source: "web"})

Track Conversions

First, choose a conversion metric. At Instacart, an item added to the cart from the search results page counts as a conversion.

Next, when a user searches, keep track of the search id. With Searchkick, you can get the id with:

results ="apple", track: true)

When a user converts, find the record and call convert.

search = Searchjoy::Search.find(params[:id])

Better yet, record the model that converted.



Don’t forget to protect the dashboard in production.


In your config/routes.rb:

authenticate :user, ->(user) { user.admin? } do
  mount Searchjoy::Engine, at: "searchjoy"

Basic Authentication

Set the following variables in your environment or an initializer.


Data Retention

Data should only be retained for as long as it’s needed. Delete older data with:

Searchjoy::Search.where("created_at < ?", 1.year.ago).find_in_batches do |searches|
  search_ids =
  Searchjoy::Conversion.where(search_id: search_ids).delete_all
  Searchjoy::Search.where(id: search_ids).delete_all

You can use Rollup to aggregate important data before you do.


Delete data for a specific user with:

user_id = 123
search_ids = Searchjoy::Search.where(user_id: user_id).pluck(:id)
Searchjoy::Conversion.where(search_id: search_ids).delete_all
Searchjoy::Search.where(id: search_ids).delete_all


To customize, create an initializer config/initializers/searchjoy.rb.

Change the time zone

Searchjoy.time_zone = "Pacific Time (US & Canada)" # defaults to

Change the number of top searches shown

Searchjoy.top_searches = 500 # defaults to 100

Link to the search results

Searchjoy.query_url = ->(search) { Rails.application.routes.url_helpers.items_path(q: search.query) }

Add additional info to the query in the live stream

Searchjoy.query_name = ->(search) { "#{search.query} #{}" }

Show the conversion name in the live stream

Searchjoy.conversion_name = ->(model) { }



Searchjoy now supports multiple conversions per search 🎉

Before updating the gem, create a migration with:

create_table :searchjoy_conversions do |t|
  t.references :search
  t.references :convertable, polymorphic: true, index: {name: "index_searchjoy_conversions_on_convertable"}
  t.datetime :created_at

Deploy and run the migration, then update the gem.

You can optionally backfill the conversions table


And optionally remove convertable from searches

remove_reference :searchjoy_searches, :convertable, polymorphic: true

You can stay with single conversions (and skip all the previous steps) by creating an initializer with:

Searchjoy.multiple_conversions = false


View the changelog


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

To get started with development and testing:

git clone
cd searchjoy
bundle install
bundle exec rake test


Search analytics made easy

License:MIT License


Language:Ruby 99.7%Language:JavaScript 0.3%