Sphinx on Rails

13,671 views

Published on

Presentation from OSDC 2008 in Sydney, on using Sphinx with Rails. The sldes don't work that well without the talk though, but it may be useful as a reference, I guess.

Published in: Technology

Sphinx on Rails

  1. Sphinx on Rails
  2. Fast and Painless Full-Text Searching
  3. Pat Allan http://freelancing-gods.com http://twitter.com/pat
  4. Searching can be ugly...
  5. SELECT * FROM users WHERE first_name LIKE '%query%' OR last_name LIKE '%query%' OR email LIKE '%query%' OR location LIKE '%query%';
  6. SELECT * FROM users WHERE (first_name LIKE '%one%' OR first_name LIKE '%two%') OR (last_name LIKE '%one%' OR last_name LIKE '%two%') ...
  7. ... very ugly
  8. Sphinx to the rescue!
  9. Indexes Documents
  10. Queries Document Indexes
  11. Similar to: • Lucene • Xapian •Ferret •Solr
  12. MySQL
  13. PostgreSQL
  14. XML
  15. • C • Perl •C++ •PHP •C# •Python •Java •Ruby •Haskell
  16. Ruby
  17. Ruby on Rails
  18. How?
  19. acts as sphinx
  20. Sphincter
  21. Ultrasphinx
  22. Thinking Sphinx
  23. script/plugin install git://github.com/freelancing-god/ thinking-sphinx.git
  24. class User < ActiveRecord::Base # end
  25. class User < ActiveRecord::Base define_index do indexes first_name indexes last_name indexes email indexes location end end
  26. rake thinking_sphinx:index rake thinking_sphinx:start
  27. SELECT * FROM users WHERE first_name LIKE '%query%' OR last_name LIKE '%query%' OR email LIKE '%query%' OR location LIKE '%query%';
  28. User.search quot;queryquot;
  29. SELECT * FROM users WHERE (first_name LIKE '%one%' OR first_name LIKE '%two%') OR (last_name LIKE '%one%' OR last_name LIKE '%two%') ...
  30. User.search quot;one twoquot;, :match_mode => :any
  31. Wait! You forgot something...
  32. Pagination
  33. @users = User.search quot;queryquot;
  34. <%= will_paginate @users %>
  35. @users = User.search quot;queryquot;, :page => (params[:page] || 0)
  36. Sorting
  37. Attributes != Fields
  38. Fields are for Searching
  39. Attributes are for Filtering and Sorting
  40. class User < ActiveRecord::Base define_index do # ... has created_at end end
  41. User.search quot;Melbournequot;, :order => :created_at
  42. class User < ActiveRecord::Base define_index do # ... indexes last_name, :sortable => true # ... end end
  43. User.search quot;Melbournequot;, :order => :last_name
  44. Filtering
  45. class User < ActiveRecord::Base define_index do # ... has active end end
  46. User.search quot;Melbournequot;, :with => {:active => 1}
  47. User.search quot;Melbournequot;, :with => { :created_at => ( 1.year.ago..Time.now ) }
  48. User.search :conditions => { :first_name => quot;Patquot; }
  49. Weighting
  50. User.search quot;Melbournequot;, :field_weights => { quot;first_namequot; => 10, quot;last_namequot; => 10, quot;locationquot; => 5 }
  51. class User < ActiveRecord::Base define_index do # ... set_property :field_weights => { quot;first_namequot; => 10, quot;last_namequot; => 10, quot;locationquot; => 5 } end end
  52. Indexing Everything
  53. Sphinx lets you dig your own grave
  54. class User < ActiveRecord::Base has_many :articles define_index do indexes articles.subject, :as => :subjects # ... end end
  55. Complex SQL = Slower Indexing
  56. Searching Everything
  57. ThinkingSphinx::Search.search( quot;queryquot; )
  58. Geo-location Searching
  59. class User < ActiveRecord::Base define_index do # ... has lat, lng end end
  60. rake thinking_sphinx:stop rake thinking_sphinx:index rake thinking_sphinx:start
  61. User.search :geo => [ -0.591376, 2.638356 ]
  62. What’s the catch?
  63. Sphinx is a bit all-or-nothing
  64. User.create( :first_name => quot;Patquot;, :last_name => quot;Allanquot; )
  65. User.search quot;Patquot; #=> []
  66. rake thinking_sphinx:index
  67. rake thinking_sphinx:index
  68. δ to the rescue
  69. δelta to the rescue
  70. class User < ActiveRecord::Base define_index do # ... set_property :delta => true end end
  71. rake thinking_sphinx:stop rake thinking_sphinx:index rake thinking_sphinx:start
  72. User.create( :first_name => quot;Patquot;, :last_name => quot;Allanquot; )
  73. User.search quot;Patquot; # => [#<User ...>]
  74. So err, what just happened?
  75. core
  76. δelta
  77. core δelta
  78. rake thinking_sphinx:index
  79. core
  80. Merb?
  81. ActiveRecord
  82. DataMapper?
  83. Soon!
  84. Well Soon-ish
  85. Okay, I’ll stop talking now...
  86. Questions?

×