redis-search 0.7.1 → 0.8.0
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 +2 -1
- data/lib/redis/search/base.rb +37 -12
- data/lib/redis/search/index.rb +36 -33
- metadata +11 -10
data/README.markdown
CHANGED
@@ -13,6 +13,7 @@ High performance real-time search (Support Chinese), index in Redis for Rails ap
|
|
13
13
|
* Real-time search
|
14
14
|
* High performance
|
15
15
|
* Segment words search and prefix match search
|
16
|
+
* Support match with alias
|
16
17
|
* Support ActiveRecord and Mongoid
|
17
18
|
* Sort results by one field
|
18
19
|
* Homophone search, pinyin search
|
@@ -31,7 +32,7 @@ in Rails application Gemfile
|
|
31
32
|
# add rmmseg if you need search by segment words
|
32
33
|
gem 'rmmseg-cpp-huacnlee', '0.2.9'
|
33
34
|
gem 'redis-namespace','~> 1.1.0'
|
34
|
-
gem 'redis-search', '0.
|
35
|
+
gem 'redis-search', '0.8.0'
|
35
36
|
|
36
37
|
install bundlers
|
37
38
|
|
data/lib/redis/search/base.rb
CHANGED
@@ -7,11 +7,13 @@ class Redis
|
|
7
7
|
# Config redis-search index for Model
|
8
8
|
# == Params:
|
9
9
|
# title_field Query field for Search
|
10
|
+
# alias_field Alias field for search, can accept multi field (String or Array type), it type is String, redis-search will split by comma
|
10
11
|
# prefix_index_enable Is use prefix index search
|
11
12
|
# ext_fields What kind fields do you need inlucde to search indexes
|
12
13
|
# score_field Give a score for search sort, need Integer value, default is `created_at`
|
13
14
|
def redis_search_index(options = {})
|
14
15
|
title_field = options[:title_field] || :title
|
16
|
+
alias_field = options[:alias_field] || nil
|
15
17
|
prefix_index_enable = options[:prefix_index_enable] || false
|
16
18
|
ext_fields = options[:ext_fields] || []
|
17
19
|
score_field = options[:score_field] || :created_at
|
@@ -33,9 +35,20 @@ class Redis
|
|
33
35
|
end
|
34
36
|
exts
|
35
37
|
end
|
38
|
+
|
39
|
+
def redis_search_alias_value(field)
|
40
|
+
return [] if field.blank? or field == "_was"
|
41
|
+
val = instance_eval("self.\#{field}").clone
|
42
|
+
return [] if !val.class.in?([String,Array])
|
43
|
+
if val.is_a?(String)
|
44
|
+
val = val.to_s.split(",")
|
45
|
+
end
|
46
|
+
val
|
47
|
+
end
|
36
48
|
|
37
49
|
def redis_search_index_create
|
38
50
|
s = Search::Index.new(:title => self.#{title_field},
|
51
|
+
:aliases => self.redis_search_alias_value(#{alias_field.inspect}),
|
39
52
|
:id => self.id,
|
40
53
|
:exts => self.redis_search_fields_to_hash(#{ext_fields.inspect}),
|
41
54
|
:type => self.class.to_s,
|
@@ -47,13 +60,25 @@ class Redis
|
|
47
60
|
s = nil
|
48
61
|
true
|
49
62
|
end
|
63
|
+
|
64
|
+
def redis_search_index_delete(titles)
|
65
|
+
titles.uniq.each do |title|
|
66
|
+
Search::Index.remove(:id => self.id, :title => title, :type => self.class.to_s)
|
67
|
+
end
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
50
71
|
|
51
|
-
before_destroy
|
52
|
-
|
53
|
-
|
72
|
+
before_destroy do
|
73
|
+
titles = []
|
74
|
+
titles = redis_search_alias_value("#{alias_field}")
|
75
|
+
titles << self.#{title_field}
|
76
|
+
|
77
|
+
redis_search_index_delete(titles)
|
54
78
|
true
|
55
79
|
end
|
56
80
|
|
81
|
+
|
57
82
|
def redis_search_index_need_reindex
|
58
83
|
index_fields_changed = false
|
59
84
|
#{ext_fields.inspect}.each do |f|
|
@@ -68,7 +93,10 @@ class Redis
|
|
68
93
|
end
|
69
94
|
end
|
70
95
|
begin
|
71
|
-
if
|
96
|
+
if self.#{title_field}_changed?
|
97
|
+
index_fields_changed = true
|
98
|
+
end
|
99
|
+
if self.#{alias_field || title_field}_changed?
|
72
100
|
index_fields_changed = true
|
73
101
|
end
|
74
102
|
rescue
|
@@ -76,15 +104,12 @@ class Redis
|
|
76
104
|
return index_fields_changed
|
77
105
|
end
|
78
106
|
|
79
|
-
after_update
|
80
|
-
def redis_search_index_remove
|
81
|
-
# DEBUG info
|
82
|
-
# puts '>>>>>>>>>>>>>>>>>>>>>>'
|
83
|
-
# puts self.redis_search_index_need_reindex
|
84
|
-
# puts self.#{title_field}_was
|
85
|
-
# puts self.#{title_field}
|
107
|
+
after_update do
|
86
108
|
if self.redis_search_index_need_reindex
|
87
|
-
|
109
|
+
titles = []
|
110
|
+
titles = redis_search_alias_value("#{alias_field}_was")
|
111
|
+
titles << self.#{title_field}_was
|
112
|
+
redis_search_index_delete(titles)
|
88
113
|
end
|
89
114
|
true
|
90
115
|
end
|
data/lib/redis/search/index.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
class Redis
|
2
2
|
module Search
|
3
3
|
class Index
|
4
|
-
attr_accessor :type, :title, :id,:score, :exts, :condition_fields, :prefix_index_enable
|
4
|
+
attr_accessor :type, :title, :id,:score, :aliases, :exts, :condition_fields, :prefix_index_enable
|
5
5
|
def initialize(options = {})
|
6
6
|
# default data
|
7
7
|
self.condition_fields = []
|
8
8
|
self.exts = []
|
9
|
+
self.aliases = []
|
9
10
|
self.prefix_index_enable = false
|
10
11
|
|
11
12
|
# set attributes value from params
|
12
13
|
options.keys.each do |k|
|
13
14
|
eval("self.#{k} = options[k]")
|
14
15
|
end
|
16
|
+
self.aliases << self.title
|
17
|
+
self.aliases.uniq!
|
15
18
|
end
|
16
19
|
|
17
20
|
def save
|
@@ -23,26 +26,26 @@ class Redis
|
|
23
26
|
|
24
27
|
# 将原始数据存入 hashes
|
25
28
|
res = Redis::Search.config.redis.hset(self.type, self.id, data.to_json)
|
26
|
-
# 保存 sets 索引,以分词的单词为key,用于后面搜索,里面存储 ids
|
27
|
-
words = Search::Index.split_words_for_index(self.title)
|
28
|
-
return if words.blank?
|
29
|
-
words.each do |word|
|
30
|
-
key = Search.mk_sets_key(self.type,word)
|
31
|
-
# word index for item id
|
32
|
-
Redis::Search.config.redis.sadd(key, self.id)
|
33
|
-
# score for search sort
|
34
|
-
Redis::Search.config.redis.set(Search.mk_score_key(self.type,self.id),self.score)
|
35
|
-
end
|
36
29
|
|
37
30
|
# 将目前的编号保存到条件(conditions)字段所创立的索引上面
|
38
31
|
self.condition_fields.each do |field|
|
39
32
|
Redis::Search.config.redis.sadd(Search.mk_condition_key(self.type,field,data[field.to_sym]), self.id)
|
40
33
|
end
|
41
|
-
|
42
|
-
#
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
|
35
|
+
# score for search sort
|
36
|
+
Redis::Search.config.redis.set(Search.mk_score_key(self.type,self.id),self.score)
|
37
|
+
|
38
|
+
# 保存 sets 索引,以分词的单词为key,用于后面搜索,里面存储 ids
|
39
|
+
self.aliases.each do |val|
|
40
|
+
words = Search::Index.split_words_for_index(val)
|
41
|
+
return if words.blank?
|
42
|
+
words.each do |word|
|
43
|
+
Redis::Search.config.redis.sadd(Search.mk_sets_key(self.type,word), self.id)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# 建立前缀索引
|
48
|
+
save_prefix_index if prefix_index_enable
|
46
49
|
end
|
47
50
|
|
48
51
|
def self.remove(options = {})
|
@@ -50,8 +53,7 @@ class Redis
|
|
50
53
|
Redis::Search.config.redis.hdel(type,options[:id])
|
51
54
|
words = Search::Index.split_words_for_index(options[:title])
|
52
55
|
words.each do |word|
|
53
|
-
|
54
|
-
Redis::Search.config.redis.srem(key, options[:id])
|
56
|
+
Redis::Search.config.redis.srem(Search.mk_sets_key(type,word), options[:id])
|
55
57
|
Redis::Search.config.redis.del(Search.mk_score_key(type,options[:id]))
|
56
58
|
end
|
57
59
|
|
@@ -70,23 +72,24 @@ class Redis
|
|
70
72
|
end
|
71
73
|
|
72
74
|
def save_prefix_index
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
words.each do |word|
|
75
|
+
self.aliases.each do |val|
|
76
|
+
words = []
|
77
|
+
words << val.downcase
|
78
|
+
Redis::Search.config.redis.sadd(Search.mk_sets_key(self.type,val), self.id)
|
79
|
+
if Search.config.pinyin_match
|
80
|
+
pinyin = Pinyin.t(val.downcase,'')
|
81
|
+
words << pinyin
|
82
|
+
Redis::Search.config.redis.sadd(Search.mk_sets_key(self.type,pinyin), self.id)
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
words.each do |word|
|
86
|
+
key = Search.mk_complete_key(self.type)
|
87
|
+
(1..(word.length)).each do |l|
|
88
|
+
prefix = word[0...l]
|
89
|
+
Redis::Search.config.redis.zadd(key, 0, prefix)
|
90
|
+
end
|
91
|
+
Redis::Search.config.redis.zadd(key, 0, word + "*")
|
88
92
|
end
|
89
|
-
Redis::Search.config.redis.zadd(key, 0, word + "*")
|
90
93
|
end
|
91
94
|
end
|
92
95
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chinese_pinyin
|
16
|
-
requirement: &
|
16
|
+
requirement: &70259274984740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,21 @@ dependencies:
|
|
21
21
|
version: 0.3.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70259274984740
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis-namespace
|
27
|
-
requirement: &
|
27
|
+
requirement: &70259274983840 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
|
-
- -
|
30
|
+
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.0.2
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70259274983840
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: redis
|
38
|
-
requirement: &
|
38
|
+
requirement: &70259274983120 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 2.1.1
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70259274983120
|
47
47
|
description: High performance real-time search (Support Chinese), index in Redis for
|
48
48
|
Rails application.
|
49
49
|
email:
|
@@ -80,9 +80,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
version: 1.3.6
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.8.
|
83
|
+
rubygems_version: 1.8.10
|
84
84
|
signing_key:
|
85
85
|
specification_version: 3
|
86
86
|
summary: High performance real-time search (Support Chinese), index in Redis for Rails
|
87
87
|
application.
|
88
88
|
test_files: []
|
89
|
+
has_rdoc:
|