Solving the
Riddle of Search
 Using Sphinx with Rails
My name is Pat
http://freelancing-gods.com

   http://twitter.com/pat
Questions?
Within Current
   Context?
Ask as we go
Jumping topics?
Please Wait
A Tute in
Two Parts
Part One:
Core Concepts
(ie: the
boring bits)
Part Two:
Beyond the
  Basics
(ie: the
fun bits)
So...
Part One:
Core Concepts
What is Sphinx?
Open Source
Search Service
http://www.sphinxsearch.com/
Similar to Ferret,
Solr, Xapian, etc
Talks to MySQL
and PostgreSQL
... and Microsoft
 SQL Server and
 Oracle in 0.9.9
Two Key Tools
indexer
Guess what
  it does
Talks to your
 database
Files away
your data
searchd
No prizes for
guessing this
   either.
searchd = search
    daemon
Runs in the
Background
Handles Search
  Requests
Does not talk to
your database.
What gets
indexed?
Documents
No, not Microsoft
   Word docs
A document is a
single database
    record
(ie: a Rails
model instance)
Documents have
   fields and
   attributes
They are not
 the same.
THEY ARE NOT
 THE SAME.
Fields are...
Textual Data
Strings
Words to
search for.
Attributes, on
the other hand...
Integers
Floats
Timestamps
Booleans
... and Strings.
     Kinda.
Strings as
 Ordinals
Huh?
Integer values
   indicating
  alphabetical
order of strings.
Useless for
Searching?
Useful for
Sorting though.
Search queries
  don’t look at
attribute values.
Sorting
Grouping
Filtering
Exact value
 matching
So, that’s
Sphinx...
But what’s
 Thinking
  Sphinx?
Ruby Library/
Rails Plugin
Hooks into
ActiveRecord
Configure
 Sphinx with
Ruby and YAML
Search with
Sphinx in Rails
What’s in it for
 me though?
Why should I
use Sphinx?
SQL does it all,
    right?
Well, maybe
But it gets messy
• Find all people
• Where any word matches
• Part of any of four fields
# given a query of ‘Pat Allan’
# assuming MySQL

SELECT * FROM people
WHERE first_name LIKE   '%Pat%'
  OR first_name LIKE...
It’s a bit long...
And that’s a
simple query!
If we use
Thinking Sphinx
# given a query of ‘Pat Allan’

Person.search quot;Pat Allanquot;,
  :match_mode => :any
Much cleaner
Can we start
coding now?
Not quite.
Indexing
Fields
What textual
data do we want
   indexed?
Enter the
 indexes
 method
class Person < ActiveRecord::Base
  # ...

 define_index do
   indexes first_name, last_name,
     location, profile
 end
...
# Combine columns into one field
indexes [first_name, last_name],
  :as => :name

# Avoid core Ruby class methods
indexes ...
Attributes
What do we want
to sort and filter
       by?
Our friend the
      has
  method
class Person < ActiveRecord::Base
  # ...

 define_index do
   # ...
   has created_at, admin, email, :id
 end

  # ...
end
# Multi-Value Attributes (MVAs)
has tags.id, :as => :tag_ids
What if I want to
sort by a field?
indexes first_name, last_name,
  :sortable => true
What does all
this code do?
Defines a SQL
query for Sphinx
Complexity
leads to slower
   indexing
So don’t forget
to add database
indexes as well!
Warning for fans
 of fixtures...
# In your define_index block:
set_property(
  :sql_range_step => 10_000_000
)
Because it’s
   SQL...
Can only use
 model columns,
not model methods
Maybe that’s not
 good enough?
Write your
own SQL!
has quot;YEAR(created_at)quot;,
  :as => :year, :type => :integer
So, we’ve set up
  our index.
  Now what?
rake thinking_sphinx:index
(in /Users/pat/Code/ruby/ts_test_2.2.0)
Generating Configuration to /Users/pat/Code/ruby/ts_test_2.2.0/
config/development...
rake thinking_sphinx:start
(in /Users/pat/Code/ruby/ts_test_2.2.0)
searchd --pidfile --config /Users/pat/Code/ruby/ts_test_2.2.0/
config/development....
rake thinking_sphinx:stop
(in /Users/pat/Code/ruby/ts_test_2.2.0)
Sphinx 0.9.8-release (r1371)
Copyright (c) 2001-2008, Andrew Aksyonoff

using conf...
rake ts:in
rake ts:start
rake ts:stop
Can we
search yet?
Person.search
Person.search quot;Pat Allanquot;
Focus that
 search on a
specific field
Person.search(quot;Rubyquot;,
  :conditions => {:name => quot;Pat Allanquot;}
)
Conditions are
not exactly like
 ActiveRecord
Strings only.
And conditions
should always
  be a Hash.
Filtering on
 Attributes
Person.search(quot;Rubyquot;,
  :with => {:admin => true}
)
Filtering
by Ranges
Person.search(quot;Rubyquot;,
  :with => {
    :created_at => 1.week.ago..Time.now
  }
)
Filtering
by Arrays
Person.search(quot;Rubyquot;,
  :with => {:tag_ids => [1, 2, 3]}
)
Matching all
Array values
Person.search(quot;Rubyquot;,
  :with_all => {:tag_ids => [1, 2, 3]}
)
Excluding
Filter Values
Person.search(quot;Rubyquot;,
  :without => {:admin => true}
)
Match Modes
:all
(The Default)
All words must
    exist in a
  document
:any
Person.search(quot;Pat Allanquot;,
  :match_mode => :any
)
One of the words
 must exist in a
  document
:phrase
The exact query
must exist in the
  document
:boolean
Use boolean
logic in search
    queries
:extended
Can match on
specific fields,
  and apply
boolean logic
Weighting
Person.search(quot;Pat Allanquot;,
  :field_weights => {
    quot;namequot;     => 100,
    quot;profilequot; => 50,
    q...
define_index do
  # ...

  set_property    :field_weights => {
    quot;namequot;        => 100,
    quot;profilequot;    ...
Sorting
:relevance
The Default
By Attributes
Or Fields flagged
   as :sortable
:attr_asc
Person.search quot;Pat Allanquot;,
  :order => :created_at
:attr_desc
Person.search quot;Pat Allanquot;,
  :order     => :created_at,
  :sort_mode => :desc
:extended
Person.search quot;Pat Allanquot;,
  :order => quot;last_name ASC,
first_name ASCquot;
:expr
Person.search quot;Pat Allanquot;,
  :sort_mode => :expr,
  :sort_by   => quot;@weight * rankingquot;
:time_segments
Person.search quot;Pat Allanquot;,
  :sort_mode => :time_segments,
  :sort_by   => quot;created_atquot;
• Last Hour
• Last Day
• Last Week
• Last Month
• Last 3 Months
• Everything Else
Sorted by
Segment, then
  Relevance
Multi-Model
 Searches
ThinkingSphinx::Search.search(
  quot;Pat Allanquot;
)
Pagination
Always On
Person.search quot;Pat Allanquot;,
  :page     => params[:page]
You can request
really big pages
    though.
Person.search quot;Pat Allanquot;,
  :per_page => 1000,
  :page     => params[:page]
If you want
massive pages...
Person.search quot;Pat Allanquot;,
  :page        => params[:page],
  :per_page    => 1_000_000,
  :max_matches => 1_000_0...
# config/sphinx.yml
development:
  max_matches: 1000000
test:
  max_matches: 1000000
production:
  max_matches: 1000000
Don’t forget to
restart Sphinx
Installing
Thinking Sphinx
Using Git?
script/plugin install
  git://github.com/freelancing-god/
  thinking-sphinx.git
git clone git://github.com/
  freelancing-god/thinking-sphinx.git
Want the gem
  instead?
sudo gem install
  freelancing-god-thinking-sphinx
  --source http://gems.github.com
# inside config/environment.rb
config.gem(
  quot;freelancing-god-thinking-sphinxquot;,
  :version => quot;1.1.6quot;,
  :...
# at the end of your Rakefile:
require 'thinking_sphinx/tasks'
Installing
  Sphinx
Windows?
Installer.
Piece of Cake.
*nix?
apt, yum, etc.
 Should be
  painless.
OS X?
Well... it can
 be a little
complicated
./configure
make
sudo make install
With
PostgreSQL?
./configure --with-pgsql=/usr/local/
  include/postgresql
make
sudo make install
pg_config --pkgincludedir
Or Use MacPorts
... if you’re using
  it for MySQL or
     PostgreSQL
        as well
Anyone still
  stuck?
Examples in the
  Sample App
git://github.com/freelancing-
    god/sphinx-tute.git
Set up Database
Hack as we go
Questions?
Afternoon
 Break?
Part Two:
Beyond the
  Basics
Delta Indexes
Why?
No single-
document
 updates
Can only process
  a full index.
Delta Index
 holds the
 changes
∆
∆
rake thinking_sphinx:index
∆
What does this
   mean?
We can track
 changes as
they happen
... at the cost of a
     little extra
     overhead.
How?
1. Add a boolean
column ‘delta’ to
   your model.
2. Tell your index
 to use a delta.
define_index do
  # ...

  set_property :delta => true
end
3. Stop,
Re-index,
 Restart.
rake thinking_sphinx:stop
rake thinking_sphinx:index
rake thinking_sphinx:start
... that’s the
    default
 approach
Datetime Deltas
define_index do
  # ...

  set_property :delta => :datetime,
    :threshold => 1.day
end
Use existing
 updated_at
  column
rake thinking_sphinx:index:delta
Please Note: Not
entirely reliable
Delayed Deltas
create_table :delayed_jobs do |t|
  # ...
end
define_index do
  # ...

  set_property :delta => :delayed
end
rake thinking_sphinx:delayed_delta
Uses delayed_job
Removes
overheard from
your web stack
Give it a Shot
Facets
Search
Summaries
define_index do
  # ...
  indexes location, country,
    :facet => true

  has admin, :facet => true
end
Person.facets(quot;Rubyquot;)
{
    :country => {
       quot;Australiaquot; =>   15,
       quot;USAquot;       =>   11,
       quot;Germanyquot;   => ...
@facets.for(:country => quot;Australiaquot;)
Give it a Shot
Extended
Configuration
config/sphinx.yml
Just like
database.yml
Global Sphinx
   settings
Common
   Example:
Partial Matching
Rai* == Rails
development:
  enable_star: 1
  min_infix_len: 1
test:
  enable_star: 1
  min_infix_len: 1
production:
  enable_star: 1
  ...
Stop,
Re-index,
 Restart.
Deployment
Using
Capistrano?
# config/deploy.rb
load 'vendor/plugins/thinking-sphinx/lib/
thinking_sphinx/deploy/capistrano'
cap   thinking_sphinx:configure
cap   thinking_sphinx:index
cap   thinking_sphinx:install:sphinx
cap   thinking_sphinx:ins...
Installing
  Sphinx
Set Sphinx index
     location
Sphinx does not
 like symlinks
# config/sphinx.yml
production:
  searchd_file_path: quot;/var/www/
sphinx-tute/shared/db/sphinx/
production/quot;
# config/deploy.rb
after quot;deploy:setupquot;,
  quot;thinking_sphinx:shared_sphinx_folderquot;
Regular
indexing via
   Cron
Geo-Searching
Need latitude
and longitude
  attributes
As floats
In Radians
define_index do
  # ...

  has latitude, longitude
end
Stop,
Re-index,
 Restart.
Bar.search(
  quot;Las Vegasquot;,
  :geo => [@lat, @lng],
  :sort => quot;@geodist ASCquot;
)
@bars.each_with_geodist do |bar,
distance|
  # distance is in metres
end
Using custom
column names?
define_index do
  # ...

  set_property(
    :latitude_attr => :updown,
    :longitude_attr => :leftright
  )
end
Geo-searching
across multiple
   models?
ThinkingSphinx::Search.search(
  quot;pancakesquot;,
  :geo            => [@lat, @lng]
  :latitude_attr => :lat,
  :longit...
Give it a Shot
Are we done yet?
http://ts.freelancing-gods.com
http://groups.google.com/
 group/thinking-sphinx
http://peepcode.com/products/
    thinking-sphinx-pdf
Questions?
Thank you.
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Rails
Upcoming SlideShare
Loading in...5
×

Solving the Riddle of Search: Using Sphinx with Rails

9,723

Published on

An introduction to using the Sphinx search service and the Thinking Sphinx library for Ruby and Rails.

Published in: Technology
2 Comments
20 Likes
Statistics
Notes
  • Best one
    Hope you are in good health. My name is AMANDA . I am a single girl, Am looking for reliable and honest person. please have a little time for me. Please reach me back amanda_n14144@yahoo.com so that i can explain all about myself .
    Best regards AMANDA.
    amanda_n14144@yahoo.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Instead of depending on a plugin you can directly configure sphnix search to your search engine. i have already done it and its pretty simple see this post http://flexlearner.wordpress.com/2009/12/03/sphinx-search/
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
9,723
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
135
Comments
2
Likes
20
Embeds 0
No embeds

No notes for slide

Solving the Riddle of Search: Using Sphinx with Rails

  1. 1. Solving the Riddle of Search Using Sphinx with Rails
  2. 2. My name is Pat
  3. 3. http://freelancing-gods.com http://twitter.com/pat
  4. 4. Questions?
  5. 5. Within Current Context?
  6. 6. Ask as we go
  7. 7. Jumping topics?
  8. 8. Please Wait
  9. 9. A Tute in Two Parts
  10. 10. Part One: Core Concepts
  11. 11. (ie: the boring bits)
  12. 12. Part Two: Beyond the Basics
  13. 13. (ie: the fun bits)
  14. 14. So...
  15. 15. Part One: Core Concepts
  16. 16. What is Sphinx?
  17. 17. Open Source Search Service
  18. 18. http://www.sphinxsearch.com/
  19. 19. Similar to Ferret, Solr, Xapian, etc
  20. 20. Talks to MySQL and PostgreSQL
  21. 21. ... and Microsoft SQL Server and Oracle in 0.9.9
  22. 22. Two Key Tools
  23. 23. indexer
  24. 24. Guess what it does
  25. 25. Talks to your database
  26. 26. Files away your data
  27. 27. searchd
  28. 28. No prizes for guessing this either.
  29. 29. searchd = search daemon
  30. 30. Runs in the Background
  31. 31. Handles Search Requests
  32. 32. Does not talk to your database.
  33. 33. What gets indexed?
  34. 34. Documents
  35. 35. No, not Microsoft Word docs
  36. 36. A document is a single database record
  37. 37. (ie: a Rails model instance)
  38. 38. Documents have fields and attributes
  39. 39. They are not the same.
  40. 40. THEY ARE NOT THE SAME.
  41. 41. Fields are...
  42. 42. Textual Data
  43. 43. Strings
  44. 44. Words to search for.
  45. 45. Attributes, on the other hand...
  46. 46. Integers
  47. 47. Floats
  48. 48. Timestamps
  49. 49. Booleans
  50. 50. ... and Strings. Kinda.
  51. 51. Strings as Ordinals
  52. 52. Huh?
  53. 53. Integer values indicating alphabetical order of strings.
  54. 54. Useless for Searching?
  55. 55. Useful for Sorting though.
  56. 56. Search queries don’t look at attribute values.
  57. 57. Sorting
  58. 58. Grouping
  59. 59. Filtering
  60. 60. Exact value matching
  61. 61. So, that’s Sphinx...
  62. 62. But what’s Thinking Sphinx?
  63. 63. Ruby Library/ Rails Plugin
  64. 64. Hooks into ActiveRecord
  65. 65. Configure Sphinx with Ruby and YAML
  66. 66. Search with Sphinx in Rails
  67. 67. What’s in it for me though?
  68. 68. Why should I use Sphinx?
  69. 69. SQL does it all, right?
  70. 70. Well, maybe
  71. 71. But it gets messy
  72. 72. • Find all people • Where any word matches • Part of any of four fields
  73. 73. # given a query of ‘Pat Allan’ # assuming MySQL SELECT * FROM people WHERE first_name LIKE '%Pat%' OR first_name LIKE '%Allan%' OR last_name LIKE '%Pat%' OR last_name LIKE '%Allan%' OR location LIKE '%Pat%' OR location LIKE '%Allan%' OR profile LIKE '%Pat%' OR profile LIKE '%Allan%';
  74. 74. It’s a bit long...
  75. 75. And that’s a simple query!
  76. 76. If we use Thinking Sphinx
  77. 77. # given a query of ‘Pat Allan’ Person.search quot;Pat Allanquot;, :match_mode => :any
  78. 78. Much cleaner
  79. 79. Can we start coding now?
  80. 80. Not quite.
  81. 81. Indexing
  82. 82. Fields
  83. 83. What textual data do we want indexed?
  84. 84. Enter the indexes method
  85. 85. class Person < ActiveRecord::Base # ... define_index do indexes first_name, last_name, location, profile end # ... end
  86. 86. # Combine columns into one field indexes [first_name, last_name], :as => :name # Avoid core Ruby class methods indexes :name # Use association columns indexes photos.captions, :as => :photos
  87. 87. Attributes
  88. 88. What do we want to sort and filter by?
  89. 89. Our friend the has method
  90. 90. class Person < ActiveRecord::Base # ... define_index do # ... has created_at, admin, email, :id end # ... end
  91. 91. # Multi-Value Attributes (MVAs) has tags.id, :as => :tag_ids
  92. 92. What if I want to sort by a field?
  93. 93. indexes first_name, last_name, :sortable => true
  94. 94. What does all this code do?
  95. 95. Defines a SQL query for Sphinx
  96. 96. Complexity leads to slower indexing
  97. 97. So don’t forget to add database indexes as well!
  98. 98. Warning for fans of fixtures...
  99. 99. # In your define_index block: set_property( :sql_range_step => 10_000_000 )
  100. 100. Because it’s SQL...
  101. 101. Can only use model columns, not model methods
  102. 102. Maybe that’s not good enough?
  103. 103. Write your own SQL!
  104. 104. has quot;YEAR(created_at)quot;, :as => :year, :type => :integer
  105. 105. So, we’ve set up our index. Now what?
  106. 106. rake thinking_sphinx:index
  107. 107. (in /Users/pat/Code/ruby/ts_test_2.2.0) Generating Configuration to /Users/pat/Code/ruby/ts_test_2.2.0/ config/development.sphinx.conf indexer --config /Users/pat/Code/ruby/ts_test_2.2.0/config/ development.sphinx.conf --all Sphinx 0.9.8-release (r1371) Copyright (c) 2001-2008, Andrew Aksyonoff using config file '/Users/pat/Code/ruby/ts_test_2.2.0/config/ development.sphinx.conf'... indexing index 'person_core'... collected 1000 docs, 0.0 MB collected 0 attr values sorted 0.0 Mvalues, 100.0% done sorted 0.0 Mhits, 100.0% done total 1000 docs, 14436 bytes total 0.191 sec, 75523.42 bytes/sec, 5231.60 docs/sec indexing index 'person_delta'... collected 0 docs, 0.0 MB collected 0 attr values sorted 0.0 Mvalues, nan% done total 0 docs, 0 bytes total 0.010 sec, 0.00 bytes/sec, 0.00 docs/sec distributed index 'person' can not be directly indexed; skipping.
  108. 108. rake thinking_sphinx:start
  109. 109. (in /Users/pat/Code/ruby/ts_test_2.2.0) searchd --pidfile --config /Users/pat/Code/ruby/ts_test_2.2.0/ config/development.sphinx.conf Sphinx 0.9.8-release (r1371) Copyright (c) 2001-2008, Andrew Aksyonoff using config file '/Users/pat/Code/ruby/ts_test_2.2.0/config/ development.sphinx.conf'... Started successfully (pid 6220).
  110. 110. rake thinking_sphinx:stop
  111. 111. (in /Users/pat/Code/ruby/ts_test_2.2.0) Sphinx 0.9.8-release (r1371) Copyright (c) 2001-2008, Andrew Aksyonoff using config file '/Users/pat/Code/ruby/ts_test_2.2.0/config/ development.sphinx.conf'... stop: succesfully sent SIGTERM to pid 6220 Stopped search daemon (pid 6220).
  112. 112. rake ts:in rake ts:start rake ts:stop
  113. 113. Can we search yet?
  114. 114. Person.search
  115. 115. Person.search quot;Pat Allanquot;
  116. 116. Focus that search on a specific field
  117. 117. Person.search(quot;Rubyquot;, :conditions => {:name => quot;Pat Allanquot;} )
  118. 118. Conditions are not exactly like ActiveRecord
  119. 119. Strings only.
  120. 120. And conditions should always be a Hash.
  121. 121. Filtering on Attributes
  122. 122. Person.search(quot;Rubyquot;, :with => {:admin => true} )
  123. 123. Filtering by Ranges
  124. 124. Person.search(quot;Rubyquot;, :with => { :created_at => 1.week.ago..Time.now } )
  125. 125. Filtering by Arrays
  126. 126. Person.search(quot;Rubyquot;, :with => {:tag_ids => [1, 2, 3]} )
  127. 127. Matching all Array values
  128. 128. Person.search(quot;Rubyquot;, :with_all => {:tag_ids => [1, 2, 3]} )
  129. 129. Excluding Filter Values
  130. 130. Person.search(quot;Rubyquot;, :without => {:admin => true} )
  131. 131. Match Modes
  132. 132. :all
  133. 133. (The Default)
  134. 134. All words must exist in a document
  135. 135. :any
  136. 136. Person.search(quot;Pat Allanquot;, :match_mode => :any )
  137. 137. One of the words must exist in a document
  138. 138. :phrase
  139. 139. The exact query must exist in the document
  140. 140. :boolean
  141. 141. Use boolean logic in search queries
  142. 142. :extended
  143. 143. Can match on specific fields, and apply boolean logic
  144. 144. Weighting
  145. 145. Person.search(quot;Pat Allanquot;, :field_weights => { quot;namequot; => 100, quot;profilequot; => 50, quot;locationquot; => 30 } )
  146. 146. define_index do # ... set_property :field_weights => { quot;namequot; => 100, quot;profilequot; => 50, quot;locationquot; => 30 } end
  147. 147. Sorting
  148. 148. :relevance
  149. 149. The Default
  150. 150. By Attributes
  151. 151. Or Fields flagged as :sortable
  152. 152. :attr_asc
  153. 153. Person.search quot;Pat Allanquot;, :order => :created_at
  154. 154. :attr_desc
  155. 155. Person.search quot;Pat Allanquot;, :order => :created_at, :sort_mode => :desc
  156. 156. :extended
  157. 157. Person.search quot;Pat Allanquot;, :order => quot;last_name ASC, first_name ASCquot;
  158. 158. :expr
  159. 159. Person.search quot;Pat Allanquot;, :sort_mode => :expr, :sort_by => quot;@weight * rankingquot;
  160. 160. :time_segments
  161. 161. Person.search quot;Pat Allanquot;, :sort_mode => :time_segments, :sort_by => quot;created_atquot;
  162. 162. • Last Hour • Last Day • Last Week • Last Month • Last 3 Months • Everything Else
  163. 163. Sorted by Segment, then Relevance
  164. 164. Multi-Model Searches
  165. 165. ThinkingSphinx::Search.search( quot;Pat Allanquot; )
  166. 166. Pagination
  167. 167. Always On
  168. 168. Person.search quot;Pat Allanquot;, :page => params[:page]
  169. 169. You can request really big pages though.
  170. 170. Person.search quot;Pat Allanquot;, :per_page => 1000, :page => params[:page]
  171. 171. If you want massive pages...
  172. 172. Person.search quot;Pat Allanquot;, :page => params[:page], :per_page => 1_000_000, :max_matches => 1_000_000
  173. 173. # config/sphinx.yml development: max_matches: 1000000 test: max_matches: 1000000 production: max_matches: 1000000
  174. 174. Don’t forget to restart Sphinx
  175. 175. Installing Thinking Sphinx
  176. 176. Using Git?
  177. 177. script/plugin install git://github.com/freelancing-god/ thinking-sphinx.git
  178. 178. git clone git://github.com/ freelancing-god/thinking-sphinx.git
  179. 179. Want the gem instead?
  180. 180. sudo gem install freelancing-god-thinking-sphinx --source http://gems.github.com
  181. 181. # inside config/environment.rb config.gem( quot;freelancing-god-thinking-sphinxquot;, :version => quot;1.1.6quot;, :lib => quot;thinking_sphinxquot; )
  182. 182. # at the end of your Rakefile: require 'thinking_sphinx/tasks'
  183. 183. Installing Sphinx
  184. 184. Windows?
  185. 185. Installer. Piece of Cake.
  186. 186. *nix?
  187. 187. apt, yum, etc. Should be painless.
  188. 188. OS X?
  189. 189. Well... it can be a little complicated
  190. 190. ./configure make sudo make install
  191. 191. With PostgreSQL?
  192. 192. ./configure --with-pgsql=/usr/local/ include/postgresql make sudo make install
  193. 193. pg_config --pkgincludedir
  194. 194. Or Use MacPorts
  195. 195. ... if you’re using it for MySQL or PostgreSQL as well
  196. 196. Anyone still stuck?
  197. 197. Examples in the Sample App
  198. 198. git://github.com/freelancing- god/sphinx-tute.git
  199. 199. Set up Database
  200. 200. Hack as we go
  201. 201. Questions?
  202. 202. Afternoon Break?
  203. 203. Part Two: Beyond the Basics
  204. 204. Delta Indexes
  205. 205. Why?
  206. 206. No single- document updates
  207. 207. Can only process a full index.
  208. 208. Delta Index holds the changes
  209. 209.
  210. 210.
  211. 211. rake thinking_sphinx:index
  212. 212.
  213. 213. What does this mean?
  214. 214. We can track changes as they happen
  215. 215. ... at the cost of a little extra overhead.
  216. 216. How?
  217. 217. 1. Add a boolean column ‘delta’ to your model.
  218. 218. 2. Tell your index to use a delta.
  219. 219. define_index do # ... set_property :delta => true end
  220. 220. 3. Stop, Re-index, Restart.
  221. 221. rake thinking_sphinx:stop rake thinking_sphinx:index rake thinking_sphinx:start
  222. 222. ... that’s the default approach
  223. 223. Datetime Deltas
  224. 224. define_index do # ... set_property :delta => :datetime, :threshold => 1.day end
  225. 225. Use existing updated_at column
  226. 226. rake thinking_sphinx:index:delta
  227. 227. Please Note: Not entirely reliable
  228. 228. Delayed Deltas
  229. 229. create_table :delayed_jobs do |t| # ... end
  230. 230. define_index do # ... set_property :delta => :delayed end
  231. 231. rake thinking_sphinx:delayed_delta
  232. 232. Uses delayed_job
  233. 233. Removes overheard from your web stack
  234. 234. Give it a Shot
  235. 235. Facets
  236. 236. Search Summaries
  237. 237. define_index do # ... indexes location, country, :facet => true has admin, :facet => true end
  238. 238. Person.facets(quot;Rubyquot;)
  239. 239. { :country => { quot;Australiaquot; => 15, quot;USAquot; => 11, quot;Germanyquot; => 8, quot;Canadaquot; => 12 }, :location => { quot;Melbournequot; => 3, # ... }
  240. 240. @facets.for(:country => quot;Australiaquot;)
  241. 241. Give it a Shot
  242. 242. Extended Configuration
  243. 243. config/sphinx.yml
  244. 244. Just like database.yml
  245. 245. Global Sphinx settings
  246. 246. Common Example: Partial Matching
  247. 247. Rai* == Rails
  248. 248. development: enable_star: 1 min_infix_len: 1 test: enable_star: 1 min_infix_len: 1 production: enable_star: 1 min_infix_len: 1
  249. 249. Stop, Re-index, Restart.
  250. 250. Deployment
  251. 251. Using Capistrano?
  252. 252. # config/deploy.rb load 'vendor/plugins/thinking-sphinx/lib/ thinking_sphinx/deploy/capistrano'
  253. 253. cap thinking_sphinx:configure cap thinking_sphinx:index cap thinking_sphinx:install:sphinx cap thinking_sphinx:install:ts cap thinking_sphinx:rebuild cap thinking_sphinx:restart cap thinking_sphinx:shared_sphinx_folder cap thinking_sphinx:start cap thinking_sphinx:stop
  254. 254. Installing Sphinx
  255. 255. Set Sphinx index location
  256. 256. Sphinx does not like symlinks
  257. 257. # config/sphinx.yml production: searchd_file_path: quot;/var/www/ sphinx-tute/shared/db/sphinx/ production/quot;
  258. 258. # config/deploy.rb after quot;deploy:setupquot;, quot;thinking_sphinx:shared_sphinx_folderquot;
  259. 259. Regular indexing via Cron
  260. 260. Geo-Searching
  261. 261. Need latitude and longitude attributes
  262. 262. As floats
  263. 263. In Radians
  264. 264. define_index do # ... has latitude, longitude end
  265. 265. Stop, Re-index, Restart.
  266. 266. Bar.search( quot;Las Vegasquot;, :geo => [@lat, @lng], :sort => quot;@geodist ASCquot; )
  267. 267. @bars.each_with_geodist do |bar, distance| # distance is in metres end
  268. 268. Using custom column names?
  269. 269. define_index do # ... set_property( :latitude_attr => :updown, :longitude_attr => :leftright ) end
  270. 270. Geo-searching across multiple models?
  271. 271. ThinkingSphinx::Search.search( quot;pancakesquot;, :geo => [@lat, @lng] :latitude_attr => :lat, :longitude_attr => :lng )
  272. 272. Give it a Shot
  273. 273. Are we done yet?
  274. 274. http://ts.freelancing-gods.com
  275. 275. http://groups.google.com/ group/thinking-sphinx
  276. 276. http://peepcode.com/products/ thinking-sphinx-pdf
  277. 277. Questions?
  278. 278. Thank you.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×