Searchkick for Smart Search Using Rails and Elasticsearch
Search has become a key component for any web application. Learn how to add smart search capabilities to your app using these frameworks.
Join the DZone community and get the full member experience.
Join For FreeHave you ever wondered, can my web app scale by learning about user searches and personalized results? Is there a one-stop solution for an autocomplete search and analytic provision to the customer and app developer? Gladly, you landed in the right place and before jumping into Searchkick, we need to understand Elasticsearch.
What Is Elasticsearch?
According to the Elasticsearch website, "Elasticsearch is a distributed, RESTful search and analytics engine capable of solving a growing number of use cases. As the heart of the Elastic Stack, it centrally stores your data so you can discover the expected and uncover the unexpected."
In short, ElasticSearch provides:
- Analytical logs for unstructured and semi-structured data.
- Full-text search experience in real time.
- Application monitoring in real-time.
- JSON Document store.
- Automatic JSON Document indexing.
- Multi-tenancy support.
- Ease in data distribution across nodes.
- Scalability ease.
Searchkick uses Elasticsearch as a default server. So, let's set up an Elasticsearch server.
How to Setup Elasticsearch Manually
Brew the Elasticsearch flavor:
brew install elasticsearch
Start and check if the Elasticsearch server install is a success.
elasticsearch
Now that we have Elasticsearch installed, let's build a Bookstore Rails app to showcase the Searchkick demo.
1) Create a new Rails application by running the command:
rails new bookstore-demo
2) Create a Book model:
rails generate scaffold Book title:string author:string genre:string price:decimal
3) Run Database creation and migration:
rake db:create db:migrate
4) Configure root on routes.rb file:
Rails.application.routes.draw do
root 'books#index'
resources :books
end
Now let's understand what Searchkick is all about. Searchkick is a smart and intelligent search engine gem that drives and creates quicker search handles based on user search activity. In our example, Searchkick can handle:
- Misspellings - Horrorr matches Horror.
- Extra whitespaces - Auto biography matches Butobiography.
- Stemming - diaries matches diary.
- Special characters.
- Reindexing with no downtime.
- Autocomplete search.
- Works with Mongoid and ActiveRecord.
- Personalize search results by user.
5) Add the Searchkick gem to the bookstore-demo app's gemfile:
gem 'searchkick'
6) Bundle the app
bundle install
7) Add the Searchkick addition to any model that needs search implemented:
class Book < ApplicationRecord
searchkick
end
8) Re-index to add data to the search index, make sure you run this command everytime Searchkick implemented model changes:
Book.reindex
9) Customize Book model to implement partial match criteria using the word_start
keyword:
class Book < ApplicationRecord
searchkick word_start: [:title, :author, :genre]
def search_data
{
title: title,
author: author,
genre: genre
}
end
end
Use alternate options depending on your criteria and needs:
:word # default
:word_start
:word_middle
:word_end
:text_start
:text_middle
:text_end
All you need is a search box to search a book by implementing the view using your favorite templating language, like ERB, HAML, or Slim.
Now that we understand Searchkick pretty well, let's look at the Searchkick gem's capabilities:
1) Querying and fetch everything:
Book.search "*"
2) Partial matches:
Book.search "science fiction" # science AND fiction
If you want to search both science and fiction:
Book.search "science fiction", operator: "or" # science AND fiction
3) Exact matches:
Book.search params[:q], fields:[{genre: :exact}, :title]
4) Phrase matches:
Book.search "Religion, Spirituality & New Age", match: :phrase
5) Languages:
searchkick word_start: [:title, :author, :genre], language: "spanish"
Check the language supported listing here.
6) Model associations callback addition to reindex.
Tracking searches and conversions:
Book.search "Great expectations", track: {user_id: current_user.id}
Instant search and autocomplete:
class Book < ApplicationRecord
searchkick match: :word_start, searchable: [:title, :author]
end
Add controller action for search criteria:
class BooksController < ApplicationController
before_action :set_book, only: [:show, :edit, :update, :destroy]
def searchcriteria
render json: Book.search(params[:query], {
fields: ["title^5", "author", "genre"],
limit: 10,
load: false,
misspellings: {below: 5}
}).map(&:title)
end
end
Search box using JavaScript on the view page:
<input type="text" id="query" name="query" />
$("#query").typeahead({
name: "book",
remote: "/books/search_criteria?query=%QUERY"
});
9) Suggestions generator:
class Book < ApplicationRecord
searchkick suggest: [:author, :title, :genre] # fields to generate suggestions
end
10) Highlight search result fields:
class Book < ApplicationRecord
searchkick highlight: [:author]
end
11) Create custom and advanced mapping:
class Book < ApplicationRecord
searchkick mappings: {
book: {
properties: {
title: {type: "string", analyzer: "keyword"},
author: {type: "string", analyzer: "keyword"}
}
}
}
end
To learn more about Searchkick and its capabilities, check out the Searchkick wiki page.
Opinions expressed by DZone contributors are their own.
Comments