Sphinx on Rails
Fast and Painless
Full-Text Searching
Pat Allan
http://freelancing-gods.com
   http://twitter.com/pat
Searching can be
     ugly...
SELECT *
FROM users
WHERE first_name   LIKE   '%query%'
  OR last_name     LIKE   '%query%'
  OR email         LIKE   '%qu...
SELECT *
FROM users
WHERE (first_name   LIKE   '%one%'
  OR   first_name   LIKE   '%two%')
  OR (last_name     LIKE   '%on...
... very ugly
Sphinx to the
  rescue!
Indexes
Documents
Queries
Document
 Indexes
Similar to:

• Lucene   • Xapian

•Ferret    •Solr
MySQL
PostgreSQL
XML
• C
           • Perl
•C++
           •PHP
•C#
           •Python
•Java
           •Ruby
•Haskell
Ruby
Ruby on Rails
How?
acts as sphinx
Sphincter
Ultrasphinx
Thinking Sphinx
script/plugin install
  git://github.com/freelancing-god/
  thinking-sphinx.git
class User < ActiveRecord::Base
  #
end
class User < ActiveRecord::Base
  define_index do
    indexes first_name
    indexes last_name
    indexes email
    index...
rake thinking_sphinx:index
rake thinking_sphinx:start
SELECT *
FROM users
WHERE first_name   LIKE   '%query%'
  OR last_name     LIKE   '%query%'
  OR email         LIKE   '%qu...
User.search quot;queryquot;
SELECT *
FROM users
WHERE (first_name   LIKE   '%one%'
  OR   first_name   LIKE   '%two%')
  OR (last_name     LIKE   '%on...
User.search quot;one twoquot;,
  :match_mode => :any
Wait! You forgot
 something...
Pagination
@users = User.search quot;queryquot;
<%= will_paginate @users %>
@users = User.search quot;queryquot;,
  :page => (params[:page] || 0)
Sorting
Attributes != Fields
Fields are for
  Searching
Attributes are for
  Filtering and
      Sorting
class User < ActiveRecord::Base
  define_index do
    # ...

    has created_at
  end
end
User.search quot;Melbournequot;,
  :order => :created_at
class User < ActiveRecord::Base
  define_index do
    # ...
    indexes last_name,
      :sortable => true
    # ...
  end...
User.search quot;Melbournequot;,
  :order => :last_name
Filtering
class User < ActiveRecord::Base
  define_index do
    # ...

    has active
  end
end
User.search quot;Melbournequot;,
  :with => {:active => 1}
User.search quot;Melbournequot;,
  :with => {
    :created_at => (
      1.year.ago..Time.now
    )
  }
User.search :conditions => {
    :first_name => quot;Patquot;
  }
Weighting
User.search quot;Melbournequot;,
  :field_weights => {
    quot;first_namequot; => 10,
    quot;last_namequot;   => 10,
  ...
class User < ActiveRecord::Base
  define_index do
    # ...
    set_property :field_weights => {
      quot;first_namequot...
Indexing
Everything
Sphinx lets
you dig your
 own grave
class User < ActiveRecord::Base
  has_many :articles

  define_index do
    indexes articles.subject,
      :as => :subjec...
Complex SQL =
Slower Indexing
Searching
Everything
ThinkingSphinx::Search.search(
  quot;queryquot;
)
Geo-location
 Searching
class User < ActiveRecord::Base
  define_index do
    # ...
    has lat, lng
  end
end
rake thinking_sphinx:stop
rake thinking_sphinx:index
rake thinking_sphinx:start
User.search :geo => [
  -0.591376, 2.638356
]
What’s the catch?
Sphinx is a bit
all-or-nothing
User.create(
  :first_name => quot;Patquot;,
  :last_name => quot;Allanquot;
)
User.search quot;Patquot; #=> []
rake thinking_sphinx:index
rake thinking_sphinx:index
δ to the rescue
δelta to the rescue
class User < ActiveRecord::Base
  define_index do
    # ...

    set_property :delta => true
  end
end
rake thinking_sphinx:stop
rake thinking_sphinx:index
rake thinking_sphinx:start
User.create(
  :first_name => quot;Patquot;,
  :last_name => quot;Allanquot;
)
User.search quot;Patquot;
# => [#<User ...>]
So err, what just
  happened?
core
δelta
core   δelta
rake thinking_sphinx:index
core
Merb?
ActiveRecord
DataMapper?
Soon!
Well Soon-ish
Okay, I’ll stop
talking now...
Questions?
Upcoming SlideShare
Loading in...5
×

Sphinx on Rails

9,664

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

    Recortar diapositivas es una manera útil de recopilar información importante para consultarla más tarde.

×