Giter VIP home page Giter VIP logo

front_axle's Introduction

FrontAxle

FrontAxle is a search engine for your Rails application. It uses the tire interface to ElasticSearch to provide search, sorting and faceting of your models.

Setting up

  • Install elasticsearch

  • Add this to your model:

class Project < ActiveRecord::Base
  include FrontAxle::Model
  • Add this to your controller:
class ProjectsController < ApplicationController
  include FrontAxle::Controller
  will_search([:index, :search])
  • Add a search route to routes.rb:
resources :projects do
  collection do
    match 'search' => 'projects#search', :via => [:get, :post], :as => :search
  end
end
  • Ensure that your application_helper defines current_user.

  • Create a Search model and table in your database to save searches.

rails g model Search parameters:string permanent:boolean name:string \
  target_model:string user:references
  • Add some methods to your Search model
def self.build(model, params)
  if params[:search_id]
    s = Search.find(params[:search_id])
    params[:q] = JSON.parse(s.parameters)
  else
    s = Search.where(:target_model => model, :parameters => params[:q].to_json, :user_id => User.current).first_or_create
  end
  if params[:searchname].present?
    s.permanent = 1
    s.name = params[:searchname]
  end
  s.update_attribute(:updated_at, Time.now)
  s.save
  return s
end

def to_description
  params = JSON.parse(parameters)
  # Return a user-facing description of the search here
end
  • Load each of your searchable models into the elasticsearch index: (see the tire documentation)
Project.create_elasticsearch_index
Project.import
  • In your model, declare what columns you want to be in your results display:
DISPLAY_COLUMNS = [
  { :column => "relevance", :ordering => "_score" },
  { :column => "id" },
  { :column => "name" }
]
  • That should be it.

Customizing

The above should get you a very basic search engine, but front_axle actually provides a lot more functionality than just that.

Better indexing

You will almost certainly want to customize the way that ElasticSearch indexes your models. See the tire and ElasticSearch documentation for what column types are available. You will certainly want to set up a mapping for your index, and you will probably also want to set up a to_indexed_json method in your model to ensure that the data is handled the way you want.

settings do
  mapping do
    indexes :id,         :index    => :not_analyzed
    indexes :name,       :analyzer => 'synsnowball', :boost => 100
    indexes :capacity,   :type => :float
    indexes :country,    :index => :not_analyzed
    indexes :start_date, :type => :date
    indexes :location,   :type => :geo_point
  end
end

Search columns

Just like the ElasticSearch mapping, most of the way that the search engine operates is customized through declarations in the model file. The DISPLAY_COLUMNS array sets which columns should appear in the result set. Each column is specified as a hash with the following parameters:

  • :column

The name of the attribute in the ElasticSearch index.

  • :header

The user-visible name of this column as displayed in the results table. (Defaults to the .humanized name of the column)

  • :code

Normally the search column simply displays the results of the attribute from ElasticSearch. If you want to do something with the value, pass in a Proc to :code instead. The Proc will receive two parameters: the result object from tire, and a helper object. (allowing you to e.g. call url_for on it.) The result of the Proc will be displayed instead.

For example:

{ :column => "price", 
  :code => lambda {|result,helper| helper.number_to_currency(result.price)} }
  • :link and :link_target

Let's suppose you have a database of books, and you want a column which represents the author (a belongs_to association). As well as displaying the author, you want the Author column to link to the author's page.

If you index the author column, you can create a link to view the author by setting :link to true.

This works, but it's ugly, because this normally requires a database hit to look up the associated object, stringify it and so on. One of the ideals of FrontAxle is that your search results should require only one call to ElasticSearch and no database hits - that way your search is nice and speedy.

If you want to optimize your search to avoid database hits, you would instead do this. First, declare your mapping to index both the author's name and their database ID:

mapping do
  ...
  indexes :author,    :as => "author.name"
  indexes :author_id, :index => :not_analyzed, :as => "author.id"
end

Now the association lookup is done once, at indexing time.

Next declare your author column like this:

{ :column => "author",
  :link_target => lambda {|result| { id: result.author_id, controller: "authors"} }
}

The result of :link_target will be fed to url_for to construct the link.

Facets

Additional search columns

If a user searches for

Customizing the display

Mapping

How a search request works

front_axle's People

Contributors

sebastianiorga avatar simoncozens avatar

Watchers

 avatar James Cloos avatar  avatar  avatar

Forkers

sebastianiorga

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.