Permalink
Browse files

Finalized search rewrite, also removed classic_pagination and moved t…

…o will_paginate (needs styling).

To access search page install sphinx:

First, install Sphinx itself. Get the 0.9.8 snapshot, then run ./configure, make, and sudo make install.

Second run rake ultrasphinx:bootstrap
  • Loading branch information...
tobi committed Sep 14, 2009
1 parent 9c234d7 commit 46b0b39a548004c011aac79b217f5660ba3ac45b
Showing with 127 additions and 1,329 deletions.
  1. +1 −2 app/controllers/categories_controller.rb
  2. +1 −2 app/controllers/forums_controller.rb
  3. +11 −7 app/controllers/search_controller.rb
  4. +1 −2 app/controllers/users_controller.rb
  5. +0 −20 app/helpers/application_helper.rb
  6. +4 −0 app/helpers/search_helper.rb
  7. +6 −7 app/models/sphinx_index.rb
  8. +12 −7 app/models/sphinx_query.rb
  9. +1 −1 app/views/categories/show.html.erb
  10. +1 −1 app/views/forums/show.html.erb
  11. +15 −3 app/views/search/results.html.erb
  12. +1 −2 app/views/users/list.rhtml
  13. +3 −0 config/environment.rb
  14. +1 −1 config/ultrasphinx/default.base
  15. +50 −6 config/ultrasphinx/development.conf
  16. +11 −0 lib/tasks/cron.rake
  17. +0 −152 vendor/plugins/classic_pagination/CHANGELOG
  18. +0 −18 vendor/plugins/classic_pagination/README
  19. +0 −22 vendor/plugins/classic_pagination/Rakefile
  20. +0 −33 vendor/plugins/classic_pagination/init.rb
  21. +0 −1 vendor/plugins/classic_pagination/install.rb
  22. +0 −405 vendor/plugins/classic_pagination/lib/pagination.rb
  23. +0 −135 vendor/plugins/classic_pagination/lib/pagination_helper.rb
  24. +0 −24 vendor/plugins/classic_pagination/test/fixtures/companies.yml
  25. +0 −9 vendor/plugins/classic_pagination/test/fixtures/company.rb
  26. +0 −7 vendor/plugins/classic_pagination/test/fixtures/developer.rb
  27. +0 −21 vendor/plugins/classic_pagination/test/fixtures/developers.yml
  28. +0 −13 vendor/plugins/classic_pagination/test/fixtures/developers_projects.yml
  29. +0 −3 vendor/plugins/classic_pagination/test/fixtures/project.rb
  30. +0 −7 vendor/plugins/classic_pagination/test/fixtures/projects.yml
  31. +0 −13 vendor/plugins/classic_pagination/test/fixtures/replies.yml
  32. +0 −5 vendor/plugins/classic_pagination/test/fixtures/reply.rb
  33. +0 −42 vendor/plugins/classic_pagination/test/fixtures/schema.sql
  34. +0 −3 vendor/plugins/classic_pagination/test/fixtures/topic.rb
  35. +0 −22 vendor/plugins/classic_pagination/test/fixtures/topics.yml
  36. +0 −117 vendor/plugins/classic_pagination/test/helper.rb
  37. +0 −38 vendor/plugins/classic_pagination/test/pagination_helper_test.rb
  38. +0 −177 vendor/plugins/classic_pagination/test/pagination_test.rb
  39. +8 −1 vendor/plugins/ultrasphinx/lib/ultrasphinx/search/internals.rb
@@ -3,8 +3,7 @@ class CategoriesController < ApplicationController
def show
@category = Category.find(params[:id], :conditions => access_conditions)
- @topic_pages = Paginator.new(self, @category.topics.count, 20, params[:page])
- @topics = @category.topics.find(:all, :limit => 20, :offset => @topic_pages.current.offset, :order => "(status = 'sticky') DESC, updated_at DESC")
+ @topics = @category.topics.paginate(:all, :limit => 20, :page => params[:page], :order => "(status = 'sticky') DESC, updated_at DESC")
@recent_posts = @category.posts.find(:all, :limit => 20, :order => 'id DESC')
@rss = category_url(@category, :format => 'xml')
@@ -8,8 +8,7 @@ def show
@recent_posts = @forum.posts.find(:all, :limit => 20, :conditions => ['category_id in (?)', Category.ids_matching(access_conditions)], :order => 'id DESC')
respond_to do |accepts|
accepts.html do
- @category_pages = Paginator.new(self, @forum.categories.count(:all, :conditions => access_conditions), 20, params[:page])
- @categories = @forum.categories.find(:all, :limit => 20, :conditions => access_conditions, :offset => @category_pages.current.offset, :order => 'id ASC')
+ @categories = @forum.categories.paginate(:all, :limit => 20, :conditions => access_conditions, :page => params[:page], :order => 'id ASC')
end
accepts.xml do
@rss = forum_url(@forum, :format => 'xml')
@@ -1,13 +1,17 @@
class SearchController < ApplicationController
def posts
- category_ids = Category.ids_matching(access_conditions)
-
- @count = Post.connection.select_value("SELECT COUNT(*) FROM posts WHERE category_id IN (#{category_ids.join(",")}) AND title LIKE '%#{params[:q]}%' OR body LIKE '%#{params[:q]}%'").to_i
-
- @result_pages = Paginator.new(self, @count, 15, params[:page])
-
- @results = Search.query(params[:q], :categories => category_ids, :limit => 15, :page => params[:page])
+ @category_ids = Category.ids_matching(access_conditions)
+
+ # Restrict search down to a single category but only if it's actually a
+ # valid one for this user.
+ search_categories = if params[:category] and @category_ids.include?(params[:category].to_i)
+ [params[:category].to_i]
+ else
+ @category_ids
+ end
+
+ @results, @search = SphinxQuery.search(params[:q], :author => params[:author], :categories => search_categories, :limit => 20, :page => params[:page])
render :action => 'results'
end
end
@@ -12,8 +12,7 @@ def list
conditions = ["level >= ?", params[:access].to_i]
end
- @user_pages = Paginator.new(self, User.count(:all, :conditions => conditions), 50, params[:page])
- @users = User.find(:all, :limit => 50, :offset => @user_pages.current.offset, :conditions => conditions, :order => "name ASC")
+ @users = User.paginate(:limit => 50, :page => params[:page], :conditions => conditions, :order => "name ASC")
end
@@ -82,26 +82,6 @@ def datetime(date)
return "unknown" if date.nil?
date.strftime("%Y-%m-%d %I:%M%p")
end
-
- def pagination_links(paginator, options={}, html_options={})
- html = []
-
- html << if paginator.current.previous
- content_tag(:span, link_to("&laquo; Previous", params.update(:page => paginator.current.previous) ), :class => 'prev')
- end
-
- html << pagination_links_each(paginator, options) do |page|
- html_options[:title] = "Go to Page #{page}"
-
- link_to(page.to_s, params.update(:page => page), html_options)
- end
-
- html << if paginator.current.next
- content_tag(:span, link_to("Next &raquo;", params.update(:page => paginator.current.next) ), :class => 'next')
- end
-
- content_tag :div, html.join, :id => 'pagination'
- end
def row_class(name = 'generic')
variable_name = "@#{name.to_s.downcase.underscore.gsub(/\s/,"_")}_counter"
@@ -10,5 +10,9 @@ def forum_link(forum)
return link_to forum.title, forum_url(forum) unless forum.nil?
"unknown forum"
end
+
+ def available_categories
+ [['All', ''],['----------', ' '], *Category.find(@category_ids).map { |c| [c.title, c.id] }]
+ end
end
View
@@ -4,17 +4,16 @@ module Post
def self.included(base)
base.is_indexed(
- :fields => [
- :created_at,
- :title
+ :fields => [
+ 'title',
+ 'body',
+ 'category_id',
+ 'created_at'
],
:include => [
- {:association_name => 'users', :field => 'name', :as => 'author'},
+ {:association_name => 'user', :field => 'name', :as => 'author'},
{:association_name => 'category', :field => 'title', :as => 'category'}
],
- :concatenate => [
- {:fields => ['title', 'body'], :as => 'body'}
- ],
:delta => true
)
View
@@ -1,12 +1,17 @@
-class SphinxQuery
+module SphinxQuery
- def query(q, options = {})
+ def self.search(q, options = {})
params = { :query => q }
- params[:weights] = { :title => 2.0 }
-
- search = Ultrasphinx::Search.new(params)
- search.excerpt
- search.results
+ params[:weights] = { :title => 1.5 }
+ params[:per_page] = options[:limit] if options[:limit]
+ params[:page] = options[:page] if options[:page]
+ params[:filters] = {}
+ params[:filters]['category_id'] = options[:categories] if options[:categories]
+ params[:filters]['author'] = options[:author] if options[:author]
+
+ @search = Ultrasphinx::Search.new(params)
+ @search.excerpt
+ return @search.results, @search
end
end
@@ -50,7 +50,7 @@
</div>
<div id="page-nav" class='clear'>
- <%= pagination_links(@topic_pages) if @topic_pages.length > 1 %>
+ <%= will_paginate @topics %>
</div>
<div id="category-edit" style="display:none">
@@ -42,7 +42,7 @@
<div id="page-nav" class='clear'>
- <%= pagination_links(@category_pages) if @category_pages.length > 1 %>
+ <%= will_paginate @categories %>
</div>
@@ -4,13 +4,25 @@
<% crumb 'Search Results', {:controller => 'search', :action => 'posts', :q => params[:q]}, :class => 'active' %>
+
+
<div class="wrapper">
- <h2>Your search <em><%= params[:q] %></em> matched <%= pluralize @count, 'result' %></h2>
+
+ <% form_tag '', :method => :get do |form| %>
+
+ <p><label for="q">Search Terms</label><input type="text" name="q" value="<%= params[:q] %>" id="q" /></p>
+ <p><label for="author">Author</label><input type="text" name="author" value="<%= params[:author]%>" id="author"></p>
+ <p><label for="categories">Category</label><%= select_tag :category, options_for_select(available_categories, params[:category].to_i) %></p>
+ <p><input type="submit" value="Search" /></p>
+
+ <% end %>
+
+ <h2>Your search <em><%= h(params[:q]) %></em> matched <%= pluralize @count, 'result' %></h2>
<% if @results.empty? %>
- <p>Your search "<strong><%= params[:q] %></strong>" did not match any topics or comments&hellip;</p>
+ <p>Your search "<strong><%= h(params[:q]) %></strong>" did not match any topics or comments&hellip;</p>
<% else %>
<table id="search-results" cellspacing="0" cellpadding="0">
@@ -41,7 +53,7 @@
</table>
<div id="page-nav" class='clear'>
- <%= pagination_links(@result_pages) if @result_pages.length > 1 %>
+ <%= will_paginate @search %>
</div>
<% end %>
@@ -11,7 +11,6 @@
<% @users.each_with_index do |user, index| %>
<li id="user-<%= user.id %>" class="<%= row_class %>">
- <%= index + 1 + @user_pages.current.offset %>
<%= link_to h(user.name), :action => 'show', :id => user.id %>
<% if admin? %>
<%= link_to_remote image_tag('/images/trash.gif'), :url => {:controller => 'accounts', :action => 'destroy', :id => user.id}, :confirm => "Are you sure you want to delete user #{h user.name}" %>
@@ -21,7 +20,7 @@
</ul>
<div id="page-nav" class='clear'>
- <%= pagination_links(@user_pages) if @user_pages.length > 1 %>
+ <%= will_paginate @users %>
</div>
</div>
View
@@ -18,6 +18,7 @@
# config.load_paths += %W( #{RAILS_ROOT}/vendor/RedCloth-3.0.3/lib )
config.gem "RedCloth", :version => '= 4.2.0'
+ config.gem 'mislav-will_paginate', :version => '>= 2.3.11', :lib => 'will_paginate', :source => 'http://gems.github.com'
# config.controller_paths += %W( #{RAILS_ROOT}/vendor/plugins/routing_navigator/lib )
@@ -62,6 +63,8 @@
HtmlEngine.default = [:textile, :whitelist_html, :autolink, :sanitize]
+SphinxModels = [Post]
+
# Include your application configuration below
require 'dash_string'
Dir[RAILS_ROOT + '/lib/extensions/*.rb'].each { |file| require file }
@@ -18,7 +18,7 @@
# .conf files. Do not symlink the .conf file to the .base file; it's wrong.
#
-<% path = "/tmp/var/db/sphinx/" %>
+<% path = ENV['HOME'] + "/tmp/var/db/sphinx/" %>
# Indexing options
indexer
@@ -1,5 +1,5 @@
-# Auto-generated at Mon Sep 07 16:20:08 -0400 2009.
+# Auto-generated at Mon Sep 14 11:49:02 -0400 2009.
# Hand modifications will be overwritten.
# /Users/tobi/Code/Ruby/opinion/config/ultrasphinx/default.base
indexer {
@@ -9,12 +9,12 @@ indexer {
searchd {
read_timeout = 5
max_children = 300
- log = /tmp/var/db/sphinx/log/searchd.log
+ log = /Users/tobi/tmp/var/db/sphinx/log/searchd.log
port = 3313
max_matches = 100000
- query_log = /tmp/var/db/sphinx/log/query.log
+ query_log = /Users/tobi/tmp/var/db/sphinx/log/query.log
seamless_rotate = 1
- pid_file = /tmp/var/db/sphinx/log/searchd.pid
+ pid_file = /Users/tobi/tmp/var/db/sphinx/log/searchd.pid
address = 0.0.0.0
}
@@ -35,8 +35,9 @@ sql_host = localhost
sql_pass =
sql_user = root
sql_query_range = SELECT MIN(id) , MAX(id) FROM posts
-sql_query = SELECT (posts.id * 1 + 0) AS id, posts.body_html AS body_html, 'Post' AS class, 0 AS class_id, UNIX_TIMESTAMP(posts.created_at) AS created_at, posts.title AS title FROM posts WHERE posts.id >= $start AND posts.id <= $end GROUP BY posts.id
+sql_query = SELECT (posts.id * 1 + 0) AS id, user.name AS author, posts.body AS body, category.title AS category, posts.category_id AS category_id, 'Post' AS class, 0 AS class_id, UNIX_TIMESTAMP(posts.created_at) AS created_at, posts.title AS title FROM posts LEFT OUTER JOIN users AS user ON user.id = posts.user_id LEFT OUTER JOIN categories AS category ON category.id = posts.category_id WHERE posts.id >= $start AND posts.id <= $end GROUP BY posts.id
+sql_attr_uint = category_id
sql_attr_uint = class_id
sql_attr_timestamp = created_at
sql_query_info = SELECT * FROM posts WHERE posts.id = (($id - 0) / 1)
@@ -54,7 +55,50 @@ index main
min_word_len = 1
stopwords =
html_strip = 0
- path = /tmp/var/db/sphinx//sphinx_index_main
+ path = /Users/tobi/tmp/var/db/sphinx//sphinx_index_main
+ docinfo = extern
+ morphology = stem_en
+}
+
+
+# Source configuration
+
+source posts_delta
+{
+ sql_range_step = 5000
+ sql_query_post =
+ sql_ranged_throttle = 0
+
+ type = mysql
+ sql_query_pre = SET SESSION group_concat_max_len = 65535
+ sql_query_pre = SET NAMES utf8
+
+sql_db = opinion_dev
+sql_host = localhost
+sql_pass =
+sql_user = root
+sql_query_range = SELECT MIN(id) , MAX(id) FROM posts WHERE posts.updated_at > DATE_SUB(NOW(), INTERVAL 88200 SECOND)
+sql_query = SELECT (posts.id * 1 + 0) AS id, user.name AS author, posts.body AS body, category.title AS category, posts.category_id AS category_id, 'Post' AS class, 0 AS class_id, UNIX_TIMESTAMP(posts.created_at) AS created_at, posts.title AS title FROM posts LEFT OUTER JOIN users AS user ON user.id = posts.user_id LEFT OUTER JOIN categories AS category ON category.id = posts.category_id WHERE posts.id >= $start AND posts.id <= $end AND posts.updated_at > DATE_SUB(NOW(), INTERVAL 88200 SECOND) GROUP BY posts.id
+
+sql_attr_uint = category_id
+sql_attr_uint = class_id
+sql_attr_timestamp = created_at
+sql_query_info = SELECT * FROM posts WHERE posts.id = (($id - 0) / 1)
+}
+
+
+# Index configuration
+
+index delta
+{
+ source = posts_delta
+ charset_type = utf-8
+ html_index_attrs =
+ charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z,
+ min_word_len = 1
+ stopwords =
+ html_strip = 0
+ path = /Users/tobi/tmp/var/db/sphinx//sphinx_index_delta
docinfo = extern
morphology = stem_en
}
View
@@ -0,0 +1,11 @@
+namespace :cron do
+
+ task :daily do
+ Rake::Task['ultrasphinx:index'].invoke
+ end
+
+ task :hourly do
+ Rake::Task['ultrasphinx:index:delta'].invoke
+ end
+
+end
Oops, something went wrong.

0 comments on commit 46b0b39

Please sign in to comment.