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
|