Thebes is a thin binding layer for Rails and Sphinx with Riddle
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
rails
railties
spec
templates
.gitignore
.rspec
Gemfile
Gemfile.lock
LICENSE
Rakefile
Readme.mkd
thebes.gemspec

Readme.mkd

Thebes

Thebes is a thin binding layer for Rails and Sphinx via Riddle and Mysql2. Thebes expects you to write Sphinx configuration files by hand and have a rich understanding of Sphinx, but provides configuration files and templates to ease the process.

Installation

To use Thebes, just add it to your Gemfile:

gem 'thebes'

# Or pin Thebes to git
# gem 'thebes',
#   :git => 'git@github.com:harvesthq/thebes.git'

Then use bundle install to update your Gemfile.lock. If your project is using Rails, you can take advantage of the generator to create your starting config files:

script/rails g sphinx_config

This will create the three config files that Thebes requires for easy setup:

  • sphinx.yml - Configuration values for your sphinx.conf files.
  • sphinx.conf.erb - The template for your sphinx.conf files.
  • sphinx_servers.yml - Configuration of Rails, which Sphinx servers to connect to.

Flavor to taste, and run rake thebes:build to generate your sphinx configuation.

Querying via Sphinx's custom protocol

Generate a query against Sphinx via Riddle:

result = Thebes::Query.run do |a|
  # a here is an instance of Riddle::Client:
  # http://rdoc.info/github/freelancing-god/riddle/master/Riddle/Client
  a.apply_filter_like_in_riddle
end 

result will be an instance of Riddle::Response. Usually you will want to call .next on it to get your returned values from Sphinx. A more complex usage example:

# sphinx_res is a raw result from Riddle.
#
sphinx_res = Thebes::Query.run do |q|

  # In Riddle, filters need to be added to a query before the
  # actual query.
  #
  q.filters << Riddle::Client::Filter.new('active', [1])

  # Pull search terms of a query.
  #
  query = params[:search_terms].split(' ').collect {|word|
    "( =#{word} | #{word} | #{word}* )"
  }.join(' ')

  q.append_query query, 'documents' # Search index 'documents'.

  # You can change the match_mode or alter the query in other
  # ways.
  #
  # q.match_mode = :expr2
end

ids, weights = [], []
sphinx_res[0][:matches].each do |match|
  ids << match[:attributes]['_id']
  weights << match[:weight]
end

# Fetch documents from the database.
#
@documents = Document.find(ids)

# Sort documents by weight.
#
@documents.sort! {|a,b| weights[ids.index(b.id)] <=> weights[ids.index(a.id)] }

Additionally, you can set procs to be run before the query block or right before the query is run:

# Usually found in config/initializers/thebes.rb
#

# Before the Thebes::Query.run block.
#
Thebes::Query.before_query = Proc.new do |q|
  q.match_mode = :any
  q.max_matches = 10
end

# Just before the query is run.
#
Thebes::Query.before_running = Proc.new do |q|
end

Querying via Sphinxql

Thebes has minimal support for querying Sphinx via the new Sphinxql syntax. Running a query returns a Mysql2::Result object.

# Do a search with SphinxQL.
#
@results = Thebes::Sphinxql::Query.run "SELECT * FROM items WHERE MATCH('Horwitz')"

@ids = @results.collect {|r| r['_id'] }

Deployment Strategy

Always check config/sphinx.conf.erb into your SCM. The config/sphinx.yml and config/sphinx_servers.yml files probably should not be checked in, and any generated config/sphinx.conf files should likely not be checked in.

Steps in a capistrano-style deployment:

  • Copy server-side config/sphinx_servers.yml and config/sphinx.yml files into place.
  • Run rake thebes:build to generate config/sphinx.conf or any other sphinx configuration files.
  • Restart searchd, run the indexer.

If you want to use a cluster of Sphinx servers, several configuration files can be generated by modifying config/sphinx.conf to generate the proper configurations. Then update config/sphinx_servers.yml to tell your running Rails app where to find any new servers.

Contributing

Fork, clone, write a test, write some code, commit, push, send a pull request. Github FTW!

This project was open-sourced by Harvest. We're hiring!