= Redis::TextSearch - Use Redis to perform text search from any type of class
This gem implements an extremely fast text search using Redis, based on the patterns from
James Gray's {lists and sets in Redis post}[http://blog.grayproductions.net/articles/lists_and_sets_in_redis]
as well as Antirez's {text search gist}[http://gist.github.com/120067]. You can use it with any type of class,
whether it be ActiveRecord, DataMapper, MongoRecord, or even a class having nothing to do with an ORM.
This is not intended to be the most full-featured text search available. For that, look into
{Sphinx}[http://www.sphinxsearch.com/], {Solr}[http://lucene.apache.org/solr/], or
{other alternatives}[http://en.wikipedia.org/wiki/Full_text_search#Open_Source_projects].
This gem is designed to (a) be extremely fast and (b) handle any (or multiple) data stores.
The only requirement this gem has is that your class must provide an +id+ instance method
which returns the ID for that instance. ActiveRecord, DataMapper, and MongoRecord all have +id+ methods which
are known to be suitable. Since "ID" can be any data type, you can even write an +id+ method of your own
that just returns a string, or an MD5 of a filename, or something else unique.
== Installation
gem install redis-textsearch
== Initialization
If you're using Rails, config/initializers/redis.rb is a good place for this:
require 'redis'
require 'redis/text_search'
Redis::TextSearch.redis = Redis.new(:host => 'localhost', :port => 6379)
== Example
Model class:
class Post < ActiveRecord::Base
include Redis::TextSearch
text_index :title, :minlength => 2
text_index :tags, :exact => true
text_index :description, :full => true # allow full-phrase "Search With Spaces"
# Using AR callback (you can call update_text_indexes anywhere on your instance)
after_save do |r|
r.update_text_indexes
end
after_destroy do |r|
r.delete_text_indexes
end
end
Create posts:
Post.create(:title => "All About Bacon", :tags => "chef nontechnical")
Post.create(:title => "All About Bacon - Part 2", :tags => "chef nontechnical")
Post.create(:title => "Homemade Belgian Waffles", :tags => "chef nontechnical")
Post.create(:title => "Using Redis with Ruby", :tags => "technical ruby redis")
Post.create(:title => "Installing Redis on Linux", :tags => "technical redis linux")
Post.create(:title => "Chef Deployment Recipes", :tags => "ruby howto chef")
Then search for them:
@posts = Post.text_search('bacon') # 2 results
@posts = Post.text_search('chef') # 4 results (tags and title)
@posts = Post.text_search('technical', 'ruby') # AND search (1 result)
@posts = Post.text_search('chef', :fields => :tags) # 3 results (only search tags)
You can pass options through to the +find+ method:
@posts = Post.text_search('redis', :order => 'updated_at desc')
@posts = Post.text_search('redis', :select => 'id,title', :limit => 50)
And do pagination (adapted from +will_paginate+):
@posts = Post.text_search('redis', :page => 1, :per_page => 10)
@posts = Post.text_search('redis', :page => 1) # uses class.per_page like will_paginate
You can also specify specific fields to search as a hash:
@posts = Post.text_search(:tags => 'chef') # 4 results
@posts = Post.text_search(:tags => ['technical','ruby']) # AND (1 result)
@posts = Post.text_search(:tags => 'redis', :title => 'linux') # 1 result
@posts = Post.text_search(:title => 'chef') # 1 result
Note that if you need to pass options to +find+ AND search specific fields, the first
hash must be in brackets:
@posts = Post.text_search({:tags => 'chef', :title => 'deployment'},
:order => 'updated_at desc')
== Author
Copyright (c) 2009-2010 {Nate Wiger}[http://nate.wiger.org]. All Rights Reserved.
Released under the {Artistic License}[http://www.opensource.org/licenses/artistic-license-2.0.php].