redis-search 0.3.2 → 0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +16 -11
 - data/lib/redis/search/base.rb +66 -0
 - data/lib/redis/search/config.rb +30 -0
 - data/lib/{redis_search/search.rb → redis/search/finder.rb} +22 -80
 - data/lib/redis/search/index.rb +57 -0
 - data/lib/redis/search/railtie.rb +9 -0
 - data/lib/redis/search/tasks.rb +40 -0
 - data/lib/redis-search.rb +6 -0
 - metadata +43 -69
 - data/lib/redis_search/base.rb +0 -57
 - data/lib/redis_search/config.rb +0 -23
 - data/lib/redis_search.rb +0 -11
 
    
        data/README.markdown
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #  
     | 
| 
      
 1 
     | 
    
         
            +
            # Redis-Search
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            High performance real-time search (Support Chinese), index in Redis for Rails application
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
         @@ -11,16 +11,15 @@ High performance real-time search (Support Chinese), index in Redis for Rails ap 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            ## Requirements
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
            * Ruby 1.9.2
         
     | 
| 
       15 
14 
     | 
    
         
             
            * Redis 2.2+
         
     | 
| 
       16 
15 
     | 
    
         | 
| 
       17 
16 
     | 
    
         
             
            ## Install
         
     | 
| 
       18 
17 
     | 
    
         | 
| 
       19 
18 
     | 
    
         
             
            in Rails application Gemfile
         
     | 
| 
       20 
19 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            	gem 'redis','2.1.1'
         
     | 
| 
      
 20 
     | 
    
         
            +
            	gem 'redis','>= 2.1.1'
         
     | 
| 
       22 
21 
     | 
    
         
             
            	gem "rmmseg-cpp-huacnlee", "0.2.8"
         
     | 
| 
       23 
     | 
    
         
            -
            	gem 'redis-search', '0. 
     | 
| 
      
 22 
     | 
    
         
            +
            	gem 'redis-search', '0.4'
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
       25 
24 
     | 
    
         
             
            install bundlers
         
     | 
| 
       26 
25 
     | 
    
         | 
| 
         @@ -30,22 +29,22 @@ install bundlers 
     | 
|
| 
       30 
29 
     | 
    
         | 
| 
       31 
30 
     | 
    
         
             
            create file in: config/initializers/redis_search.rb
         
     | 
| 
       32 
31 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                require " 
     | 
| 
      
 32 
     | 
    
         
            +
                require "redis-search"
         
     | 
| 
       34 
33 
     | 
    
         
             
                redis = Redis.new(:host => "127.0.0.1",:port => "6379")
         
     | 
| 
       35 
34 
     | 
    
         
             
                # change redis database to 3, you need use a special database for search feature.
         
     | 
| 
       36 
35 
     | 
    
         
             
                redis.select(3)
         
     | 
| 
       37 
     | 
    
         
            -
                 
     | 
| 
      
 36 
     | 
    
         
            +
                Redis::Search.configure do |config|
         
     | 
| 
       38 
37 
     | 
    
         
             
                  config.redis = redis
         
     | 
| 
       39 
38 
     | 
    
         
             
                  config.complete_max_length = 100
         
     | 
| 
       40 
39 
     | 
    
         
             
                end
         
     | 
| 
       41 
40 
     | 
    
         | 
| 
       42 
41 
     | 
    
         
             
            ## Usage
         
     | 
| 
       43 
42 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
            bind  
     | 
| 
      
 43 
     | 
    
         
            +
            bind Redis::Search callback event, it will to rebuild search indexes when data create or update.
         
     | 
| 
       45 
44 
     | 
    
         | 
| 
       46 
45 
     | 
    
         
             
                class Post
         
     | 
| 
       47 
46 
     | 
    
         
             
                  include Mongoid::Document
         
     | 
| 
       48 
     | 
    
         
            -
                  include  
     | 
| 
      
 47 
     | 
    
         
            +
                  include Redis::Search
         
     | 
| 
       49 
48 
     | 
    
         | 
| 
       50 
49 
     | 
    
         
             
                  field :title
         
     | 
| 
       51 
50 
     | 
    
         
             
                  field :body
         
     | 
| 
         @@ -63,7 +62,7 @@ bind RedisSearch callback event, it will to rebuild search indexes when data cre 
     | 
|
| 
       63 
62 
     | 
    
         | 
| 
       64 
63 
     | 
    
         
             
                class User
         
     | 
| 
       65 
64 
     | 
    
         
             
                  include Mongoid::Document
         
     | 
| 
       66 
     | 
    
         
            -
                  include  
     | 
| 
      
 65 
     | 
    
         
            +
                  include Redis::Search
         
     | 
| 
       67 
66 
     | 
    
         | 
| 
       68 
67 
     | 
    
         
             
                  field :name
         
     | 
| 
       69 
68 
     | 
    
         
             
                  field :tagline
         
     | 
| 
         @@ -77,15 +76,21 @@ bind RedisSearch callback event, it will to rebuild search indexes when data cre 
     | 
|
| 
       77 
76 
     | 
    
         
             
                class SearchController < ApplicationController
         
     | 
| 
       78 
77 
     | 
    
         
             
                  # GET /searchs?q=title
         
     | 
| 
       79 
78 
     | 
    
         
             
                  def index
         
     | 
| 
       80 
     | 
    
         
            -
                     
     | 
| 
      
 79 
     | 
    
         
            +
                    Redis::Search.query("Post", params[:q])
         
     | 
| 
       81 
80 
     | 
    
         
             
                  end
         
     | 
| 
       82 
81 
     | 
    
         | 
| 
       83 
82 
     | 
    
         
             
                  # GET /search_users?q=j
         
     | 
| 
       84 
83 
     | 
    
         
             
                  def search_users
         
     | 
| 
       85 
     | 
    
         
            -
                     
     | 
| 
      
 84 
     | 
    
         
            +
                    Redis::Search.complete("Post", params[:q])
         
     | 
| 
       86 
85 
     | 
    
         
             
                  end
         
     | 
| 
       87 
86 
     | 
    
         
             
                end
         
     | 
| 
       88 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
            ## Index data to Redis
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            If you are first install it in you old project, or your Redis cache lose, you can use this command to rebuild indexes.
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                $ rake redis_search:index
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
       89 
94 
     | 
    
         
             
            ## Benchmark test
         
     | 
| 
       90 
95 
     | 
    
         | 
| 
       91 
96 
     | 
    
         
             
            * [https://gist.github.com/1150933](https://gist.github.com/1150933)
         
     | 
| 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            class Redis
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Search
         
     | 
| 
      
 4 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def redis_search_index(options = {})
         
     | 
| 
      
 8 
     | 
    
         
            +
                    title_field = options[:title_field] || :title
         
     | 
| 
      
 9 
     | 
    
         
            +
                    prefix_index_enable = options[:prefix_index_enable] || false
         
     | 
| 
      
 10 
     | 
    
         
            +
                    ext_fields = options[:ext_fields] || []
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
                    # store Model name to indexed_models for Rake tasks
         
     | 
| 
      
 13 
     | 
    
         
            +
                    Search.indexed_models = [] if Search.indexed_models == nil
         
     | 
| 
      
 14 
     | 
    
         
            +
                    Search.indexed_models << self
         
     | 
| 
      
 15 
     | 
    
         
            +
                    # bind instance methods and callback events
         
     | 
| 
      
 16 
     | 
    
         
            +
                    class_eval %(
         
     | 
| 
      
 17 
     | 
    
         
            +
                      def redis_search_ext_fields(ext_fields)
         
     | 
| 
      
 18 
     | 
    
         
            +
                        exts = {}
         
     | 
| 
      
 19 
     | 
    
         
            +
                        ext_fields.each do |f|
         
     | 
| 
      
 20 
     | 
    
         
            +
                          exts[f] = instance_eval(f.to_s)
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        exts
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                      after_create :redis_search_index_create
         
     | 
| 
      
 26 
     | 
    
         
            +
                      def redis_search_index_create
         
     | 
| 
      
 27 
     | 
    
         
            +
                        s = Search::Index.new(:title => self.#{title_field}, 
         
     | 
| 
      
 28 
     | 
    
         
            +
                                       :id => self.id, 
         
     | 
| 
      
 29 
     | 
    
         
            +
                                       :exts => self.redis_search_ext_fields(#{ext_fields.inspect}), 
         
     | 
| 
      
 30 
     | 
    
         
            +
                                       :type => self.class.to_s,
         
     | 
| 
      
 31 
     | 
    
         
            +
                                       :prefix_index_enable => #{prefix_index_enable})
         
     | 
| 
      
 32 
     | 
    
         
            +
                        s.save
         
     | 
| 
      
 33 
     | 
    
         
            +
                        # release s
         
     | 
| 
      
 34 
     | 
    
         
            +
                        s = nil
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      before_destroy :redis_search_index_remove
         
     | 
| 
      
 38 
     | 
    
         
            +
                      def redis_search_index_remove
         
     | 
| 
      
 39 
     | 
    
         
            +
                        Search::Index.remove(:id => self.id, :title => self.#{title_field}, :type => self.class.to_s)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                      before_update :redis_search_index_update
         
     | 
| 
      
 43 
     | 
    
         
            +
                      def redis_search_index_update
         
     | 
| 
      
 44 
     | 
    
         
            +
                        index_fields_changed = false
         
     | 
| 
      
 45 
     | 
    
         
            +
                        #{ext_fields.inspect}.each do |f|
         
     | 
| 
      
 46 
     | 
    
         
            +
                          next if f.to_s == "id"
         
     | 
| 
      
 47 
     | 
    
         
            +
                          if instance_eval(f.to_s + "_changed?")
         
     | 
| 
      
 48 
     | 
    
         
            +
                            index_fields_changed = true
         
     | 
| 
      
 49 
     | 
    
         
            +
                          end
         
     | 
| 
      
 50 
     | 
    
         
            +
                        end
         
     | 
| 
      
 51 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 52 
     | 
    
         
            +
                          if(self.#{title_field}_changed?)
         
     | 
| 
      
 53 
     | 
    
         
            +
                            index_fields_changed = true
         
     | 
| 
      
 54 
     | 
    
         
            +
                          end
         
     | 
| 
      
 55 
     | 
    
         
            +
                        rescue
         
     | 
| 
      
 56 
     | 
    
         
            +
                        end
         
     | 
| 
      
 57 
     | 
    
         
            +
                        if index_fields_changed
         
     | 
| 
      
 58 
     | 
    
         
            +
                          Search::Index.remove(:id => self.id, :title => self.#{title_field}_was, :type => self.class.to_s)
         
     | 
| 
      
 59 
     | 
    
         
            +
                          self.redis_search_index_create
         
     | 
| 
      
 60 
     | 
    
         
            +
                        end
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
                    )
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            class Redis
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Search
         
     | 
| 
      
 4 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_accessor :config, :indexed_models
         
     | 
| 
      
 6 
     | 
    
         
            +
                
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def configure
         
     | 
| 
      
 8 
     | 
    
         
            +
                    yield self.config ||= Config.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
              
         
     | 
| 
      
 12 
     | 
    
         
            +
                class Config
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # Redis 
         
     | 
| 
      
 14 
     | 
    
         
            +
                  attr_accessor :redis
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # Debug toggle
         
     | 
| 
      
 16 
     | 
    
         
            +
                  attr_accessor :debug
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # config for max length of content with Redis::Search.complete method,default 100
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # Please change this with your real data length, short is fast
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # For example: You use complete search for your User model name field, and the "name" as max length in 15 chars, then you can set here to 15
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # warring! The long content will can't be found, if the config length less than real content.
         
     | 
| 
      
 21 
     | 
    
         
            +
                  attr_accessor :complete_max_length
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 24 
     | 
    
         
            +
                    self.debug = false
         
     | 
| 
      
 25 
     | 
    
         
            +
                    self.redis = nil
         
     | 
| 
      
 26 
     | 
    
         
            +
                    self.complete_max_length = 100
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,15 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # coding: utf-8
         
     | 
| 
       2 
2 
     | 
    
         
             
            require "rmmseg"
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
               
     | 
| 
       5 
     | 
    
         
            -
                attr_accessor :type, :title, :id, :exts, :prefix_index_enable
         
     | 
| 
       6 
     | 
    
         
            -
                def initialize(options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                  self.exts = []
         
     | 
| 
       8 
     | 
    
         
            -
                  options.keys.each do |k|
         
     | 
| 
       9 
     | 
    
         
            -
                    eval("self.#{k} = options[k]")
         
     | 
| 
       10 
     | 
    
         
            -
                  end
         
     | 
| 
       11 
     | 
    
         
            -
                end
         
     | 
| 
       12 
     | 
    
         
            -
              
         
     | 
| 
      
 3 
     | 
    
         
            +
            class Redis
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Search
         
     | 
| 
       13 
5 
     | 
    
         
             
                def self.split(text)
         
     | 
| 
       14 
6 
     | 
    
         
             
                  algor = RMMSeg::Algorithm.new(text)
         
     | 
| 
       15 
7 
     | 
    
         
             
                  words = []
         
     | 
| 
         @@ -22,7 +14,7 @@ module RedisSearch 
     | 
|
| 
       22 
14 
     | 
    
         
             
                end
         
     | 
| 
       23 
15 
     | 
    
         | 
| 
       24 
16 
     | 
    
         
             
                def self.warn(msg)
         
     | 
| 
       25 
     | 
    
         
            -
                  puts "[ 
     | 
| 
      
 17 
     | 
    
         
            +
                  puts "[Redis::Search][warn]: #{msg}"
         
     | 
| 
       26 
18 
     | 
    
         
             
                end
         
     | 
| 
       27 
19 
     | 
    
         | 
| 
       28 
20 
     | 
    
         
             
                # 生成 uuid,用于作为 hashes 的 field, sets 关键词的值
         
     | 
| 
         @@ -33,56 +25,6 @@ module RedisSearch 
     | 
|
| 
       33 
25 
     | 
    
         
             
                def self.mk_complete_key(type)
         
     | 
| 
       34 
26 
     | 
    
         
             
                  "Compl#{type}"
         
     | 
| 
       35 
27 
     | 
    
         
             
                end
         
     | 
| 
       36 
     | 
    
         
            -
              
         
     | 
| 
       37 
     | 
    
         
            -
                def self.word?(word)
         
     | 
| 
       38 
     | 
    
         
            -
                  return !/^[\w\u4e00-\u9fa5]+$/i.match(word.force_encoding("UTF-8")).blank?
         
     | 
| 
       39 
     | 
    
         
            -
                end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                def save
         
     | 
| 
       42 
     | 
    
         
            -
                  return if self.title.blank?
         
     | 
| 
       43 
     | 
    
         
            -
                  data = {:title => self.title, :id => self.id, :type => self.type}
         
     | 
| 
       44 
     | 
    
         
            -
                  self.exts.each do |f|
         
     | 
| 
       45 
     | 
    
         
            -
                    data[f[0]] = f[1]
         
     | 
| 
       46 
     | 
    
         
            -
                  end
         
     | 
| 
       47 
     | 
    
         
            -
                
         
     | 
| 
       48 
     | 
    
         
            -
                  # 将原始数据存入 hashes
         
     | 
| 
       49 
     | 
    
         
            -
                  res = RedisSearch.config.redis.hset(self.type, self.id, data.to_json)
         
     | 
| 
       50 
     | 
    
         
            -
                  # 保存 sets 索引,以分词的单词为key,用于后面搜索,里面存储 ids
         
     | 
| 
       51 
     | 
    
         
            -
                  words = Search.split(self.title)
         
     | 
| 
       52 
     | 
    
         
            -
                  return if words.blank?
         
     | 
| 
       53 
     | 
    
         
            -
                  words.each do |word|
         
     | 
| 
       54 
     | 
    
         
            -
                    next if not Search.word?(word)
         
     | 
| 
       55 
     | 
    
         
            -
                    key = Search.mk_sets_key(self.type,word)
         
     | 
| 
       56 
     | 
    
         
            -
                    RedisSearch.config.redis.sadd(key, self.id)
         
     | 
| 
       57 
     | 
    
         
            -
                  end
         
     | 
| 
       58 
     | 
    
         
            -
                  
         
     | 
| 
       59 
     | 
    
         
            -
                  # 建立前最索引
         
     | 
| 
       60 
     | 
    
         
            -
                  if prefix_index_enable
         
     | 
| 
       61 
     | 
    
         
            -
                    save_prefix_index
         
     | 
| 
       62 
     | 
    
         
            -
                  end
         
     | 
| 
       63 
     | 
    
         
            -
                end
         
     | 
| 
       64 
     | 
    
         
            -
              
         
     | 
| 
       65 
     | 
    
         
            -
                def save_prefix_index
         
     | 
| 
       66 
     | 
    
         
            -
                  word = self.title.downcase
         
     | 
| 
       67 
     | 
    
         
            -
                  RedisSearch.config.redis.sadd(Search.mk_sets_key(self.type,self.title), self.id)
         
     | 
| 
       68 
     | 
    
         
            -
                  key = Search.mk_complete_key(self.type)
         
     | 
| 
       69 
     | 
    
         
            -
                  (1..(word.length)).each do |l|
         
     | 
| 
       70 
     | 
    
         
            -
                    prefix = word[0...l]
         
     | 
| 
       71 
     | 
    
         
            -
                    RedisSearch.config.redis.zadd(key, 0, prefix)
         
     | 
| 
       72 
     | 
    
         
            -
                  end
         
     | 
| 
       73 
     | 
    
         
            -
                  RedisSearch.config.redis.zadd(key, 0, word + "*")
         
     | 
| 
       74 
     | 
    
         
            -
                end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                def self.remove(options = {})
         
     | 
| 
       77 
     | 
    
         
            -
                  type = options[:type]
         
     | 
| 
       78 
     | 
    
         
            -
                  RedisSearch.config.redis.hdel(type,options[:id])
         
     | 
| 
       79 
     | 
    
         
            -
                  words = Search.split(options[:title])
         
     | 
| 
       80 
     | 
    
         
            -
                  words.each do |word|
         
     | 
| 
       81 
     | 
    
         
            -
                    next if not Search.word?(word)
         
     | 
| 
       82 
     | 
    
         
            -
                    key = Search.mk_sets_key(type,word)
         
     | 
| 
       83 
     | 
    
         
            -
                    RedisSearch.config.redis.srem(key, options[:id])
         
     | 
| 
       84 
     | 
    
         
            -
                  end
         
     | 
| 
       85 
     | 
    
         
            -
                end
         
     | 
| 
       86 
28 
     | 
    
         | 
| 
       87 
29 
     | 
    
         
             
                # Use for short title search, this method is search by chars, for example Tag, User, Category ...
         
     | 
| 
       88 
30 
     | 
    
         
             
                # 
         
     | 
| 
         @@ -91,24 +33,24 @@ module RedisSearch 
     | 
|
| 
       91 
33 
     | 
    
         
             
                #   w         search char
         
     | 
| 
       92 
34 
     | 
    
         
             
                #   :limit    result limit
         
     | 
| 
       93 
35 
     | 
    
         
             
                # h3. usage:
         
     | 
| 
       94 
     | 
    
         
            -
                # *  
     | 
| 
       95 
     | 
    
         
            -
                # *  
     | 
| 
       96 
     | 
    
         
            -
                # *  
     | 
| 
       97 
     | 
    
         
            -
                # *  
     | 
| 
      
 36 
     | 
    
         
            +
                # * Redis::Search.complete("Tag","r") => ["Ruby","Rails", "REST", "Redis", "Redmine"]
         
     | 
| 
      
 37 
     | 
    
         
            +
                # * Redis::Search.complete("Tag","re") => ["Redis", "Redmine"]
         
     | 
| 
      
 38 
     | 
    
         
            +
                # * Redis::Search.complete("Tag","red") => ["Redis", "Redmine"]
         
     | 
| 
      
 39 
     | 
    
         
            +
                # * Redis::Search.complete("Tag","redi") => ["Redis"]
         
     | 
| 
       98 
40 
     | 
    
         
             
                def self.complete(type, w, options = {})
         
     | 
| 
       99 
41 
     | 
    
         
             
                  limit = options[:limit] || 10 
         
     | 
| 
       100 
42 
     | 
    
         | 
| 
       101 
43 
     | 
    
         
             
                  prefix_matchs = []
         
     | 
| 
       102 
44 
     | 
    
         
             
                  # This is not random, try to get replies < MTU size
         
     | 
| 
       103 
     | 
    
         
            -
                  rangelen =  
     | 
| 
      
 45 
     | 
    
         
            +
                  rangelen = Redis::Search.config.complete_max_length
         
     | 
| 
       104 
46 
     | 
    
         
             
                  prefix = w.downcase
         
     | 
| 
       105 
47 
     | 
    
         
             
                  key = Search.mk_complete_key(type)
         
     | 
| 
       106 
48 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
                  start =  
     | 
| 
      
 49 
     | 
    
         
            +
                  start = Redis::Search.config.redis.zrank(key,prefix)
         
     | 
| 
       108 
50 
     | 
    
         
             
                  return [] if !start
         
     | 
| 
       109 
51 
     | 
    
         
             
                  count = limit
         
     | 
| 
       110 
52 
     | 
    
         
             
                  max_range = start+(rangelen*limit)-1
         
     | 
| 
       111 
     | 
    
         
            -
                  range =  
     | 
| 
      
 53 
     | 
    
         
            +
                  range = Redis::Search.config.redis.zrange(key,start,max_range)
         
     | 
| 
       112 
54 
     | 
    
         
             
                  while prefix_matchs.length <= count
         
     | 
| 
       113 
55 
     | 
    
         
             
                    start += rangelen
         
     | 
| 
       114 
56 
     | 
    
         
             
                    break if !range or range.length == 0
         
     | 
| 
         @@ -128,16 +70,16 @@ module RedisSearch 
     | 
|
| 
       128 
70 
     | 
    
         
             
                  words = prefix_matchs.uniq.collect { |w| Search.mk_sets_key(type,w) }
         
     | 
| 
       129 
71 
     | 
    
         
             
                  if words.length > 1
         
     | 
| 
       130 
72 
     | 
    
         
             
                    temp_store_key = "tmpsunionstore:#{words.join("+")}"   
         
     | 
| 
       131 
     | 
    
         
            -
                    if ! 
     | 
| 
      
 73 
     | 
    
         
            +
                    if !Redis::Search.config.redis.exists(temp_store_key)
         
     | 
| 
       132 
74 
     | 
    
         
             
                      # 将多个词语组合对比,得到并集,并存入临时区域   
         
     | 
| 
       133 
     | 
    
         
            -
                       
     | 
| 
      
 75 
     | 
    
         
            +
                      Redis::Search.config.redis.sunionstore(temp_store_key,*words)
         
     | 
| 
       134 
76 
     | 
    
         
             
                      # 将临时搜索设为1天后自动清除
         
     | 
| 
       135 
     | 
    
         
            -
                       
     | 
| 
      
 77 
     | 
    
         
            +
                      Redis::Search.config.redis.expire(temp_store_key,86400)
         
     | 
| 
       136 
78 
     | 
    
         
             
                    end
         
     | 
| 
       137 
79 
     | 
    
         
             
                    # 根据需要的数量取出 ids
         
     | 
| 
       138 
     | 
    
         
            -
                    ids =  
     | 
| 
      
 80 
     | 
    
         
            +
                    ids = Redis::Search.config.redis.sort(temp_store_key,:limit => [0,limit])
         
     | 
| 
       139 
81 
     | 
    
         
             
                  else
         
     | 
| 
       140 
     | 
    
         
            -
                    ids =  
     | 
| 
      
 82 
     | 
    
         
            +
                    ids = Redis::Search.config.redis.sort(words.first,:limit => [0,limit])
         
     | 
| 
       141 
83 
     | 
    
         
             
                  end
         
     | 
| 
       142 
84 
     | 
    
         
             
                  return [] if ids.blank?
         
     | 
| 
       143 
85 
     | 
    
         
             
                  hmget(type,ids)
         
     | 
| 
         @@ -150,7 +92,7 @@ module RedisSearch 
     | 
|
| 
       150 
92 
     | 
    
         
             
                #   text         search text
         
     | 
| 
       151 
93 
     | 
    
         
             
                #   :limit    result limit
         
     | 
| 
       152 
94 
     | 
    
         
             
                # h3. usage:
         
     | 
| 
       153 
     | 
    
         
            -
                # *  
     | 
| 
      
 95 
     | 
    
         
            +
                # * Redis::Search.query("Tag","Ruby vs Python")
         
     | 
| 
       154 
96 
     | 
    
         
             
                def self.query(type, text,options = {})
         
     | 
| 
       155 
97 
     | 
    
         
             
                  result = []
         
     | 
| 
       156 
98 
     | 
    
         
             
                  return result if text.strip.blank?
         
     | 
| 
         @@ -162,17 +104,17 @@ module RedisSearch 
     | 
|
| 
       162 
104 
     | 
    
         
             
                  return result if words.blank?
         
     | 
| 
       163 
105 
     | 
    
         
             
                  temp_store_key = "tmpinterstore:#{words.join("+")}"
         
     | 
| 
       164 
106 
     | 
    
         
             
                  if words.length > 1
         
     | 
| 
       165 
     | 
    
         
            -
                    if ! 
     | 
| 
      
 107 
     | 
    
         
            +
                    if !Redis::Search.config.redis.exists(temp_store_key)
         
     | 
| 
       166 
108 
     | 
    
         
             
                      # 将多个词语组合对比,得到交集,并存入临时区域
         
     | 
| 
       167 
     | 
    
         
            -
                       
     | 
| 
      
 109 
     | 
    
         
            +
                      Redis::Search.config.redis.sinterstore(temp_store_key,*words)
         
     | 
| 
       168 
110 
     | 
    
         
             
                      # 将临时搜索设为1天后自动清除
         
     | 
| 
       169 
     | 
    
         
            -
                       
     | 
| 
      
 111 
     | 
    
         
            +
                      Redis::Search.config.redis.expire(temp_store_key,86400)
         
     | 
| 
       170 
112 
     | 
    
         
             
                    end
         
     | 
| 
       171 
113 
     | 
    
         
             
                    # 根据需要的数量取出 ids
         
     | 
| 
       172 
     | 
    
         
            -
                    ids =  
     | 
| 
      
 114 
     | 
    
         
            +
                    ids = Redis::Search.config.redis.sort(temp_store_key,:limit => [0,limit])
         
     | 
| 
       173 
115 
     | 
    
         
             
                  else
         
     | 
| 
       174 
116 
     | 
    
         
             
                    # 根据需要的数量取出 ids
         
     | 
| 
       175 
     | 
    
         
            -
                    ids =  
     | 
| 
      
 117 
     | 
    
         
            +
                    ids = Redis::Search.config.redis.sort(words.first,:limit => [0,limit])
         
     | 
| 
       176 
118 
     | 
    
         
             
                  end
         
     | 
| 
       177 
119 
     | 
    
         
             
                  hmget(type,ids, :sort_field => sort_field)
         
     | 
| 
       178 
120 
     | 
    
         
             
                end
         
     | 
| 
         @@ -182,7 +124,7 @@ module RedisSearch 
     | 
|
| 
       182 
124 
     | 
    
         
             
                    result = []
         
     | 
| 
       183 
125 
     | 
    
         
             
                    sort_field = options[:sort_field] || "id"
         
     | 
| 
       184 
126 
     | 
    
         
             
                    return result if ids.blank?
         
     | 
| 
       185 
     | 
    
         
            -
                     
     | 
| 
      
 127 
     | 
    
         
            +
                    Redis::Search.config.redis.hmget(type,*ids).each do |r|
         
     | 
| 
       186 
128 
     | 
    
         
             
                      begin
         
     | 
| 
       187 
129 
     | 
    
         
             
                        result << JSON.parse(r)
         
     | 
| 
       188 
130 
     | 
    
         
             
                      rescue => e
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Redis
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Search
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Index
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_accessor :type, :title, :id, :exts, :prefix_index_enable
         
     | 
| 
      
 5 
     | 
    
         
            +
                  def initialize(options = {})
         
     | 
| 
      
 6 
     | 
    
         
            +
                    self.exts = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                    options.keys.each do |k|
         
     | 
| 
      
 8 
     | 
    
         
            +
                      eval("self.#{k} = options[k]")
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def save
         
     | 
| 
      
 13 
     | 
    
         
            +
                    return if self.title.blank?
         
     | 
| 
      
 14 
     | 
    
         
            +
                    data = {:title => self.title, :id => self.id, :type => self.type}
         
     | 
| 
      
 15 
     | 
    
         
            +
                    self.exts.each do |f|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      data[f[0]] = f[1]
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    # 将原始数据存入 hashes
         
     | 
| 
      
 20 
     | 
    
         
            +
                    res = Redis::Search.config.redis.hset(self.type, self.id, data.to_json)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    # 保存 sets 索引,以分词的单词为key,用于后面搜索,里面存储 ids
         
     | 
| 
      
 22 
     | 
    
         
            +
                    words = Search.split(self.title)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    return if words.blank?
         
     | 
| 
      
 24 
     | 
    
         
            +
                    words.each do |word|
         
     | 
| 
      
 25 
     | 
    
         
            +
                      key = Search.mk_sets_key(self.type,word)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      Redis::Search.config.redis.sadd(key, self.id)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    # 建立前最索引
         
     | 
| 
      
 30 
     | 
    
         
            +
                    if prefix_index_enable
         
     | 
| 
      
 31 
     | 
    
         
            +
                      save_prefix_index
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def save_prefix_index
         
     | 
| 
      
 36 
     | 
    
         
            +
                    word = self.title.downcase
         
     | 
| 
      
 37 
     | 
    
         
            +
                    Redis::Search.config.redis.sadd(Search.mk_sets_key(self.type,self.title), self.id)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    key = Search.mk_complete_key(self.type)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    (1..(word.length)).each do |l|
         
     | 
| 
      
 40 
     | 
    
         
            +
                      prefix = word[0...l]
         
     | 
| 
      
 41 
     | 
    
         
            +
                      Redis::Search.config.redis.zadd(key, 0, prefix)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    Redis::Search.config.redis.zadd(key, 0, word + "*")
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  
         
     | 
| 
      
 46 
     | 
    
         
            +
                  def self.remove(options = {})
         
     | 
| 
      
 47 
     | 
    
         
            +
                    type = options[:type]
         
     | 
| 
      
 48 
     | 
    
         
            +
                    Redis::Search.config.redis.hdel(type,options[:id])
         
     | 
| 
      
 49 
     | 
    
         
            +
                    words = Search.split(options[:title])
         
     | 
| 
      
 50 
     | 
    
         
            +
                    words.each do |word|
         
     | 
| 
      
 51 
     | 
    
         
            +
                      key = Search.mk_sets_key(type,word)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      Redis::Search.config.redis.srem(key, options[:id])
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "redis-search"
         
     | 
| 
      
 3 
     | 
    
         
            +
            namespace :redis_search do
         
     | 
| 
      
 4 
     | 
    
         
            +
              desc "Redis-Search index data to Redis"
         
     | 
| 
      
 5 
     | 
    
         
            +
              task :index => :environment do
         
     | 
| 
      
 6 
     | 
    
         
            +
                tm = Time.now
         
     | 
| 
      
 7 
     | 
    
         
            +
                count = 0
         
     | 
| 
      
 8 
     | 
    
         
            +
                puts "redis-search index".upcase.rjust(120)
         
     | 
| 
      
 9 
     | 
    
         
            +
                puts "-"*120
         
     | 
| 
      
 10 
     | 
    
         
            +
                puts "Now indexing search to Redis...".rjust(120)
         
     | 
| 
      
 11 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 12 
     | 
    
         
            +
                Redis::Search.indexed_models.each do |klass|
         
     | 
| 
      
 13 
     | 
    
         
            +
                  print "[#{klass.to_s}]"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  if klass.superclass.to_s == "ActiveRecord::Base"
         
     | 
| 
      
 15 
     | 
    
         
            +
                    klass.find_in_batches(:batch_size => 1000) do |items|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      items.each do |item|
         
     | 
| 
      
 17 
     | 
    
         
            +
                        item.redis_search_index_create
         
     | 
| 
      
 18 
     | 
    
         
            +
                  			item = nil
         
     | 
| 
      
 19 
     | 
    
         
            +
                  			count += 1
         
     | 
| 
      
 20 
     | 
    
         
            +
                        print "."
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  elsif klass.included_modules.collect { |m| m.to_s }.include?("Mongoid::Document")
         
     | 
| 
      
 24 
     | 
    
         
            +
                    klass.all.each do |item|
         
     | 
| 
      
 25 
     | 
    
         
            +
                      item.redis_search_index_create
         
     | 
| 
      
 26 
     | 
    
         
            +
                			item = nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                			count += 1
         
     | 
| 
      
 28 
     | 
    
         
            +
                      print "."
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  else
         
     | 
| 
      
 31 
     | 
    
         
            +
                    puts "skiped, not support this ORM in current."
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  puts ""
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 36 
     | 
    
         
            +
                puts "-"*120
         
     | 
| 
      
 37 
     | 
    
         
            +
                puts "Indexed #{count} rows  |  Time spend: #{(Time.now - tm)}s".rjust(120)
         
     | 
| 
      
 38 
     | 
    
         
            +
                puts "Rebuild Index done.".rjust(120)
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/redis-search.rb
    ADDED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,103 +1,77 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            --- !ruby/object:Gem::Specification 
     | 
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: redis-search
         
     | 
| 
       3 
     | 
    
         
            -
            version: !ruby/object:Gem::Version 
     | 
| 
       4 
     | 
    
         
            -
               
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: '0.4'
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
     | 
    
         
            -
              segments: 
         
     | 
| 
       7 
     | 
    
         
            -
              - 0
         
     | 
| 
       8 
     | 
    
         
            -
              - 3
         
     | 
| 
       9 
     | 
    
         
            -
              - 2
         
     | 
| 
       10 
     | 
    
         
            -
              version: 0.3.2
         
     | 
| 
       11 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       12 
     | 
    
         
            -
            authors: 
     | 
| 
      
 7 
     | 
    
         
            +
            authors:
         
     | 
| 
       13 
8 
     | 
    
         
             
            - Jason Lee
         
     | 
| 
       14 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       15 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       16 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2011-09-22 00:00:00.000000000Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 14 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
       21 
15 
     | 
    
         
             
              name: rmmseg-cpp-huacnlee
         
     | 
| 
       22 
     | 
    
         
            -
               
     | 
| 
       23 
     | 
    
         
            -
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 16 
     | 
    
         
            +
              requirement: &2153202040 !ruby/object:Gem::Requirement
         
     | 
| 
       24 
17 
     | 
    
         
             
                none: false
         
     | 
| 
       25 
     | 
    
         
            -
                requirements: 
     | 
| 
      
 18 
     | 
    
         
            +
                requirements:
         
     | 
| 
       26 
19 
     | 
    
         
             
                - - ~>
         
     | 
| 
       27 
     | 
    
         
            -
                  - !ruby/object:Gem::Version 
     | 
| 
       28 
     | 
    
         
            -
                    hash: 7
         
     | 
| 
       29 
     | 
    
         
            -
                    segments: 
         
     | 
| 
       30 
     | 
    
         
            -
                    - 0
         
     | 
| 
       31 
     | 
    
         
            -
                    - 2
         
     | 
| 
       32 
     | 
    
         
            -
                    - 8
         
     | 
| 
      
 20 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
       33 
21 
     | 
    
         
             
                    version: 0.2.8
         
     | 
| 
       34 
22 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       35 
     | 
    
         
            -
              version_requirements: *id001
         
     | 
| 
       36 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency 
         
     | 
| 
       37 
     | 
    
         
            -
              name: redis
         
     | 
| 
       38 
23 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       39 
     | 
    
         
            -
               
     | 
| 
      
 24 
     | 
    
         
            +
              version_requirements: *2153202040
         
     | 
| 
      
 25 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 26 
     | 
    
         
            +
              name: redis
         
     | 
| 
      
 27 
     | 
    
         
            +
              requirement: &2153198300 !ruby/object:Gem::Requirement
         
     | 
| 
       40 
28 
     | 
    
         
             
                none: false
         
     | 
| 
       41 
     | 
    
         
            -
                requirements: 
     | 
| 
       42 
     | 
    
         
            -
                - -  
     | 
| 
       43 
     | 
    
         
            -
                  - !ruby/object:Gem::Version 
     | 
| 
       44 
     | 
    
         
            -
                    hash: 9
         
     | 
| 
       45 
     | 
    
         
            -
                    segments: 
         
     | 
| 
       46 
     | 
    
         
            -
                    - 2
         
     | 
| 
       47 
     | 
    
         
            -
                    - 1
         
     | 
| 
       48 
     | 
    
         
            -
                    - 1
         
     | 
| 
      
 29 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 30 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 31 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
       49 
32 
     | 
    
         
             
                    version: 2.1.1
         
     | 
| 
       50 
33 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       51 
     | 
    
         
            -
               
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 35 
     | 
    
         
            +
              version_requirements: *2153198300
         
     | 
| 
      
 36 
     | 
    
         
            +
            description: High performance real-time search (Support Chinese), index in Redis for
         
     | 
| 
      
 37 
     | 
    
         
            +
              Rails application.
         
     | 
| 
      
 38 
     | 
    
         
            +
            email:
         
     | 
| 
       54 
39 
     | 
    
         
             
            - huacnlee@gmail.com
         
     | 
| 
       55 
40 
     | 
    
         
             
            executables: []
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
41 
     | 
    
         
             
            extensions: []
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
42 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
            - lib/ 
     | 
| 
       63 
     | 
    
         
            -
            - lib/ 
     | 
| 
       64 
     | 
    
         
            -
            - lib/ 
     | 
| 
       65 
     | 
    
         
            -
            - lib/ 
     | 
| 
      
 43 
     | 
    
         
            +
            files:
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/redis/search/base.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/redis/search/config.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/redis/search/finder.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - lib/redis/search/index.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - lib/redis/search/railtie.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - lib/redis/search/tasks.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            - lib/redis-search.rb
         
     | 
| 
       66 
51 
     | 
    
         
             
            - README.markdown
         
     | 
| 
       67 
52 
     | 
    
         
             
            homepage: http://github.com/huacnlee/redis-search
         
     | 
| 
       68 
53 
     | 
    
         
             
            licenses: []
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
54 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       71 
55 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
            require_paths: 
         
     | 
| 
      
 56 
     | 
    
         
            +
            require_paths:
         
     | 
| 
       74 
57 
     | 
    
         
             
            - lib
         
     | 
| 
       75 
     | 
    
         
            -
            required_ruby_version: !ruby/object:Gem::Requirement 
     | 
| 
      
 58 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
       76 
59 
     | 
    
         
             
              none: false
         
     | 
| 
       77 
     | 
    
         
            -
              requirements: 
     | 
| 
       78 
     | 
    
         
            -
              - -  
     | 
| 
       79 
     | 
    
         
            -
                - !ruby/object:Gem::Version 
     | 
| 
       80 
     | 
    
         
            -
                   
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                  - 0
         
     | 
| 
       83 
     | 
    
         
            -
                  version: "0"
         
     | 
| 
       84 
     | 
    
         
            -
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 60 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 61 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 62 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 63 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 64 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       85 
65 
     | 
    
         
             
              none: false
         
     | 
| 
       86 
     | 
    
         
            -
              requirements: 
     | 
| 
       87 
     | 
    
         
            -
              - -  
     | 
| 
       88 
     | 
    
         
            -
                - !ruby/object:Gem::Version 
     | 
| 
       89 
     | 
    
         
            -
                  hash: 23
         
     | 
| 
       90 
     | 
    
         
            -
                  segments: 
         
     | 
| 
       91 
     | 
    
         
            -
                  - 1
         
     | 
| 
       92 
     | 
    
         
            -
                  - 3
         
     | 
| 
       93 
     | 
    
         
            -
                  - 6
         
     | 
| 
      
 66 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 67 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 68 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
       94 
69 
     | 
    
         
             
                  version: 1.3.6
         
     | 
| 
       95 
70 
     | 
    
         
             
            requirements: []
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
71 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       98 
     | 
    
         
            -
            rubygems_version: 1.8. 
     | 
| 
      
 72 
     | 
    
         
            +
            rubygems_version: 1.8.6
         
     | 
| 
       99 
73 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       100 
74 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       101 
     | 
    
         
            -
            summary: High performance real-time search (Support Chinese), index in Redis for Rails 
     | 
| 
      
 75 
     | 
    
         
            +
            summary: High performance real-time search (Support Chinese), index in Redis for Rails
         
     | 
| 
      
 76 
     | 
    
         
            +
              application.
         
     | 
| 
       102 
77 
     | 
    
         
             
            test_files: []
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
    
        data/lib/redis_search/base.rb
    DELETED
    
    | 
         @@ -1,57 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module RedisSearch
         
     | 
| 
       2 
     | 
    
         
            -
              extend ActiveSupport::Concern
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              module ClassMethods
         
     | 
| 
       5 
     | 
    
         
            -
                def redis_search_index(options = {})
         
     | 
| 
       6 
     | 
    
         
            -
                  title_field = options[:title_field] || :title
         
     | 
| 
       7 
     | 
    
         
            -
                  prefix_index_enable = options[:prefix_index_enable] || false
         
     | 
| 
       8 
     | 
    
         
            -
                  ext_fields = options[:ext_fields] || []
         
     | 
| 
       9 
     | 
    
         
            -
                  class_eval %(
         
     | 
| 
       10 
     | 
    
         
            -
                    def redis_search_ext_fields(ext_fields)
         
     | 
| 
       11 
     | 
    
         
            -
                      exts = {}
         
     | 
| 
       12 
     | 
    
         
            -
                      ext_fields.each do |f|
         
     | 
| 
       13 
     | 
    
         
            -
                        exts[f] = instance_eval(f.to_s)
         
     | 
| 
       14 
     | 
    
         
            -
                      end
         
     | 
| 
       15 
     | 
    
         
            -
                      exts
         
     | 
| 
       16 
     | 
    
         
            -
                    end
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                    after_create :redis_search_index_create
         
     | 
| 
       19 
     | 
    
         
            -
                    def redis_search_index_create
         
     | 
| 
       20 
     | 
    
         
            -
                      s = Search.new(:title => self.#{title_field}, :id => self.id, 
         
     | 
| 
       21 
     | 
    
         
            -
                                      :exts => self.redis_search_ext_fields(#{ext_fields}), 
         
     | 
| 
       22 
     | 
    
         
            -
                                      :type => self.class.to_s,
         
     | 
| 
       23 
     | 
    
         
            -
                                      :prefix_index_enable => #{prefix_index_enable})
         
     | 
| 
       24 
     | 
    
         
            -
                      s.save
         
     | 
| 
       25 
     | 
    
         
            -
                      # release s
         
     | 
| 
       26 
     | 
    
         
            -
                      s = nil
         
     | 
| 
       27 
     | 
    
         
            -
                    end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                    before_destroy :redis_search_index_remove
         
     | 
| 
       30 
     | 
    
         
            -
                    def redis_search_index_remove
         
     | 
| 
       31 
     | 
    
         
            -
                      Search.remove(:id => self.id, :title => self.#{title_field}, :type => self.class.to_s)
         
     | 
| 
       32 
     | 
    
         
            -
                    end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                    before_update :redis_search_index_update
         
     | 
| 
       35 
     | 
    
         
            -
                    def redis_search_index_update
         
     | 
| 
       36 
     | 
    
         
            -
                      index_fields_changed = false
         
     | 
| 
       37 
     | 
    
         
            -
                      #{ext_fields}.each do |f|
         
     | 
| 
       38 
     | 
    
         
            -
                        next if f.to_s == "id"
         
     | 
| 
       39 
     | 
    
         
            -
                        if instance_eval(f.to_s + "_changed?")
         
     | 
| 
       40 
     | 
    
         
            -
                          index_fields_changed = true
         
     | 
| 
       41 
     | 
    
         
            -
                        end
         
     | 
| 
       42 
     | 
    
         
            -
                      end
         
     | 
| 
       43 
     | 
    
         
            -
                      begin
         
     | 
| 
       44 
     | 
    
         
            -
                        if(self.#{title_field}_changed?)
         
     | 
| 
       45 
     | 
    
         
            -
                          index_fields_changed = true
         
     | 
| 
       46 
     | 
    
         
            -
                        end
         
     | 
| 
       47 
     | 
    
         
            -
                      rescue
         
     | 
| 
       48 
     | 
    
         
            -
                      end
         
     | 
| 
       49 
     | 
    
         
            -
                      if index_fields_changed
         
     | 
| 
       50 
     | 
    
         
            -
                        Search.remove(:id => self.id, :title => self.#{title_field}_was, :type => self.class.to_s)
         
     | 
| 
       51 
     | 
    
         
            -
                        self.redis_search_index_create
         
     | 
| 
       52 
     | 
    
         
            -
                      end
         
     | 
| 
       53 
     | 
    
         
            -
                    end
         
     | 
| 
       54 
     | 
    
         
            -
                  )
         
     | 
| 
       55 
     | 
    
         
            -
                end
         
     | 
| 
       56 
     | 
    
         
            -
              end
         
     | 
| 
       57 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/redis_search/config.rb
    DELETED
    
    | 
         @@ -1,23 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module RedisSearch
         
     | 
| 
       2 
     | 
    
         
            -
              class << self
         
     | 
| 
       3 
     | 
    
         
            -
                attr_accessor :config
         
     | 
| 
       4 
     | 
    
         
            -
              end
         
     | 
| 
       5 
     | 
    
         
            -
              
         
     | 
| 
       6 
     | 
    
         
            -
              class Config
         
     | 
| 
       7 
     | 
    
         
            -
                # Redis 
         
     | 
| 
       8 
     | 
    
         
            -
                attr_accessor :redis
         
     | 
| 
       9 
     | 
    
         
            -
                # Debug toggle
         
     | 
| 
       10 
     | 
    
         
            -
                attr_accessor :debug
         
     | 
| 
       11 
     | 
    
         
            -
                # config for max length of content with RedisSearch:Search.complete method,default 100
         
     | 
| 
       12 
     | 
    
         
            -
                # Please change this with your real data length, short is fast
         
     | 
| 
       13 
     | 
    
         
            -
                # For example: You use complete search for your User model name field, and the "name" as max length in 15 chars, then you can set here to 15
         
     | 
| 
       14 
     | 
    
         
            -
                # warring! The long content will can't be found, if the config length less than real content.
         
     | 
| 
       15 
     | 
    
         
            -
                attr_accessor :complete_max_length
         
     | 
| 
       16 
     | 
    
         
            -
                
         
     | 
| 
       17 
     | 
    
         
            -
                def initialize
         
     | 
| 
       18 
     | 
    
         
            -
                  self.debug = false
         
     | 
| 
       19 
     | 
    
         
            -
                  self.redis = nil
         
     | 
| 
       20 
     | 
    
         
            -
                  self.complete_max_length = 100
         
     | 
| 
       21 
     | 
    
         
            -
                end
         
     | 
| 
       22 
     | 
    
         
            -
              end
         
     | 
| 
       23 
     | 
    
         
            -
            end
         
     |