Thebes ====== Thebes is a thin binding layer for [Rails](http://rubyonrails.org/) and [Sphinx](http://sphinxsearch.com/) via [Riddle](https://github.com/freelancing-god/riddle) and [Mysql2](https://github.com/brianmario/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](http://rdoc.info/github/freelancing-god/riddle/master/Riddle/Client/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](http://sphinxsearch.com/docs/manual-0.9.9.html#sphinxql). Running a query returns a [Mysql2::Result](http://rdoc.info/github/brianmario/mysql2/master/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](http://getharvest.com/). [We're hiring!](http://www.getharvest.com/careers)