Lunar

A minimalistic search index implemented using Redis, taking advantage of its powerful sorted sets and the ability to do set intersection and union.

Results are sorted by their word score, which is stored as the score in the Redis sorted set.

Examples

class Item < Ohm::Model
  attribute :name
  attribute :description

protected
  def write
    super
    index
  end

  def index
    Lunar::Index.create 'Item' do |i|
      i.key  id
      i.attr :name, name
      i.attr :description, description
    end

    # You can also do this, no problem
    Lunar::Index.create Item do |i|
      i.key  id
      i.attr :name, name
      i.attr :description, description
    end

    # Or to avoid name ties...
    Lunar::Index.create self.class do |i|
      i.key  id
      i.attr :name, name
      i.attr :description, description
    end

    Lunar::Index.create Item do |i|
      i.key id
      i.fuzzy   :name, name # this has a 100 character limit on name
                            # for performance reasons
      i.integer :cost, cost
      i.float   :voting_quotient, voting_quotient
    end
  end
end

# Searching...
# You can just straight out search keywords
Lunar.search(Item, "iphone")

# Or opt to filter by field
Lunar.search(Item, :name => "iphone", :description => "mobile")

# For fuzzy declared fields you can currently only search 
# using a fuzzy strategy exclusively, e.g.
Lunar.search(Item, :fuzzy => { :name => "i" })
# i, ip, iph, ipho, iphone, 3, 3g, 3gs all would match 'iPhone 3Gs'

# For integer / float types, you can do range searches on them e.g.
Lunar.search(Item, :cost => 300..500, :voting_quotient => 10..20)

# Or using the pagination gem with this:
@items = Lunar.search(Item, "iphone")
paginate @items, :per_page => 10, :page => 1

# If you want to be cheap about CPU cycles you can increase the
# default `:ttl` of search results (which is 30)

# Somewhere in config/initializers or init.rb, you decide...
Lunar.ttl = 300 # search results would be the same for 5 minutes.
                # for high write public sites, this may be a good
                # option as people don't really expect their stuff to
                # be searchable right away on public content sites.