redis-search 1.0.0.beta1 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3db9e3cf11d6d82edb9366ec887db853a684468
4
- data.tar.gz: 349c2ad7333803b7f868cabd5ee4053f216b9e14
3
+ metadata.gz: 7f2a414c25a8c0f48c9cc236fdb4c905da7bd5e4
4
+ data.tar.gz: 3b9074ed892c0711245c342fcd1c381140ea17d8
5
5
  SHA512:
6
- metadata.gz: e1d2dcf8826e6c4e0e3a9414fdc0a8f1b11fc9d0cf024f5c6d5ab27e56e7da3c436f5ab20d1c487f6e2feab09d24462de24cee03209ecccf5c4ce7c51a56d423
7
- data.tar.gz: 9389c3f640c4ff76719507d681fb0d8ba4bc24cb7d36544617c76c4d209709121ec87e052e2ae4e6d52ecbb9cba3e09b212aafc1fa07e025c1dbc0a840dffbf1
6
+ metadata.gz: 765e256b56b74776f33275ddfe8dfb8aac31ccfd283398d27e29057eb94e2db3808f1dd3ac2025a7dbe34ac10b0e9a23d5a31bbc2fd5e061e591be6af4662433
7
+ data.tar.gz: b1b642a1701492a20b2b5db3856e03ac787f28e6a1e0aa57791445f5cffd27248c6a4d7a77c0e4dd47ef9f4ae67d18d391f06f5f538ebb290f0deb7260552ae6
data/README.md CHANGED
@@ -13,7 +13,7 @@ High performance real-time search (Support Chinese), index in Redis for Rails ap
13
13
 
14
14
  * Real-time search
15
15
  * High performance
16
- * Segment words search and prefix match search
16
+ * Prefix match search
17
17
  * Support match with alias
18
18
  * Support ActiveRecord and Mongoid
19
19
  * Sort results by one field
@@ -54,8 +54,6 @@ Redis::Search.configure do |config|
54
54
  config.redis = redis
55
55
  config.complete_max_length = 100
56
56
  config.pinyin_match = true
57
- # use rmmseg, true to disable it, it can save memroy
58
- config.disable_rmmseg = false
59
57
  end
60
58
  ```
61
59
 
@@ -70,10 +68,10 @@ class Post < ActiveRecord::Base
70
68
  belongs_to :user
71
69
  belongs_to :category
72
70
 
73
- redis_search_index(title_field: :title,
74
- score_field: :hits,
75
- condition_fields: [:user_id, :category_id],
76
- ext_fields: [:category_name])
71
+ redis_search title_field: :title,
72
+ score_field: :hits,
73
+ condition_fields: [:user_id, :category_id],
74
+ ext_fields: [:category_name]
77
75
 
78
76
  def category_name
79
77
  self.category.name
@@ -87,24 +85,18 @@ class User < ActiveRecord::Base
87
85
 
88
86
  serialize :alias_names, Array
89
87
 
90
- redis_search_index(title_field: :name,
91
- alias_field: :alias_names,
92
- prefix_index_enable: true,
93
- score_field: :followers_count,
94
- ext_fields: [:email, :tagline])
88
+ redis_search title_field: :name,
89
+ alias_field: :alias_names,
90
+ score_field: :followers_count,
91
+ ext_fields: [:email, :tagline]
95
92
  end
96
93
  ```
97
94
 
98
95
  ```ruby
99
96
  class SearchController < ApplicationController
100
- # GET /searchs?q=title
101
- def index
102
- Redis::Search.query("Post", params[:q], conditions: { user_id: 12 })
103
- end
104
-
105
97
  # GET /search_users?q=j
106
98
  def search_users
107
- Redis::Search.complete("Post", params[:q], conditions: { user_id: 12, category_id: 4 })
99
+ Post.prefix_match(params[:q], conditions: { user_id: 12, category_id: 4 })
108
100
  end
109
101
  end
110
102
  ```
@@ -38,8 +38,7 @@ class Redis
38
38
  exts: redis_search_fields_to_hash(redis_search_options[:ext_fields]),
39
39
  type: redis_search_options[:class_name] || self.class.name,
40
40
  condition_fields: redis_search_options[:condition_fields],
41
- score: send(redis_search_options[:score_field]).to_i,
42
- prefix_index_enable: redis_search_options[:prefix_index_enable]
41
+ score: send(redis_search_options[:score_field]).to_i
43
42
  }
44
43
 
45
44
  s = Search::Index.new(opts)
@@ -114,13 +113,11 @@ class Redis
114
113
  # == Params:
115
114
  # title_field Query field for Search
116
115
  # alias_field Alias field for search, can accept multi field (String or Array type) it type is String, redis-search will split by comma
117
- # prefix_index_enable Is use prefix index search
118
116
  # ext_fields What kind fields do you need inlucde to search indexes
119
117
  # score_field Give a score for search sort, need Integer value, default is `created_at`
120
- def redis_search_index(opts = {})
118
+ def redis_search(opts = {})
121
119
  opts[:title_field] ||= :title
122
120
  opts[:alias_field] ||= nil
123
- opts[:prefix_index_enable] ||= false
124
121
  opts[:ext_fields] ||= []
125
122
  opts[:score_field] ||= :created_at
126
123
  opts[:condition_fields] ||= []
@@ -139,6 +136,15 @@ class Redis
139
136
  class_variable_set('@@redis_search_options'.freeze, opts)
140
137
  end
141
138
 
139
+ def redis_search_index(opts = {})
140
+ Kernel.warn 'DEPRECATION WARNING: redis_search_index is deprecated, use redis_search instead. '
141
+ redis_search(opts)
142
+ end
143
+
144
+ def prefix_match(q, opts = {})
145
+ Redis::Search.complete(self.name, q, opts)
146
+ end
147
+
142
148
  def redis_search_index_batch_create(batch_size = 1000, progressbar = false)
143
149
  count = 0
144
150
  if ancestors.collect(&:to_s).include?('ActiveRecord::Base'.freeze)
@@ -5,12 +5,6 @@ class Redis
5
5
 
6
6
  def configure
7
7
  yield @config ||= Config.new
8
-
9
- unless @config.disable_rmmseg
10
- require 'rmmseg'
11
- # loading RMMSeg chinese word dicts.
12
- RMMSeg::Dictionary.load_dictionaries
13
- end
14
8
  end
15
9
  end
16
10
 
@@ -29,15 +23,12 @@ class Redis
29
23
  # When you search "de" will -> 得|的|德...
30
24
  # When you search "得" will -> "de" -> 得|的|德...
31
25
  attr_accessor :pinyin_match
32
- # Disable RMMSeg, if you don't need, disable this will save memory. (true|false) default = true
33
- attr_accessor :disable_rmmseg
34
26
 
35
27
  def initialize
36
28
  @debug = false
37
29
  @redis = nil
38
30
  @complete_max_length = 100
39
31
  @pinyin_match = false
40
- @disable_rmmseg = false
41
32
  end
42
33
  end
43
34
  end
@@ -2,11 +2,6 @@
2
2
  class Redis
3
3
  module Search
4
4
  class << self
5
- # use rmmseg to split words
6
- def split(text)
7
- _split(text)
8
- end
9
-
10
5
  # Use for short title search, this method is search by chars, for example Tag, User, Category ...
11
6
  #
12
7
  # h3. params:
@@ -98,108 +93,13 @@ class Redis
98
93
  hmget(type, ids)
99
94
  end
100
95
 
101
- # Search items, this will split words by Libmmseg
102
- #
103
- # h3. params:
104
- # type model name
105
- # text search text
106
- # :limit result limit
107
- #
108
- # h3. usage:
109
- # * Redis::Search.query("Tag","Ruby vs Python")
110
- #
111
- def query(type, text, options = {})
112
- tm = Time.now
113
- result = []
114
- limit = options[:limit] || 10
115
- sort_field = options[:sort_field] || 'id'
116
- conditions = options[:conditions] || []
117
-
118
- # 如果搜索文本和查询条件均没有,那就直接返回 []
119
- return result if text.strip.blank? && conditions.blank?
120
-
121
- words = split(text)
122
- words = words.collect { |w| mk_sets_key(type, w) }
123
-
124
- condition_keys = []
125
- unless conditions.blank?
126
- conditions = conditions[0] if conditions.is_a?(Array)
127
- conditions.keys.each do |c|
128
- condition_keys << mk_condition_key(type, c, conditions[c])
129
- end
130
- # 将条件的 key 放入关键词搜索集合内,用于 sinterstore 搜索
131
- words += condition_keys
132
- end
133
-
134
- return result if words.blank?
135
-
136
- temp_store_key = "tmpinterstore:#{words.join('+')}"
137
-
138
- if words.length > 1
139
- unless config.redis.exists(temp_store_key)
140
- config.redis.pipelined do
141
- # 将多个词语组合对比,得到交集,并存入临时区域
142
- config.redis.sinterstore(temp_store_key, *words)
143
- # 将临时搜索设为1天后自动清除
144
- config.redis.expire(temp_store_key, 86_400)
145
-
146
- # 拼音搜索
147
- if config.pinyin_match
148
- pinyin_words = split_pinyin(text)
149
- pinyin_words = pinyin_words.collect { |w| mk_sets_key(type, w) }
150
- pinyin_words += condition_keys
151
- temp_sunion_key = "tmpsunionstore:#{words.join('+')}"
152
- temp_pinyin_store_key = "tmpinterstore:#{pinyin_words.join('+')}"
153
- # 找出拼音的
154
- config.redis.sinterstore(temp_pinyin_store_key, *pinyin_words)
155
- # 合并中文和拼音的搜索结果
156
- config.redis.sunionstore(temp_sunion_key, *[temp_store_key, temp_pinyin_store_key])
157
- # 将临时搜索设为1天后自动清除
158
- config.redis.expire(temp_pinyin_store_key, 86_400)
159
- config.redis.expire(temp_sunion_key, 86_400)
160
- end
161
- temp_store_key = temp_sunion_key
162
- end
163
- end
164
- else
165
- temp_store_key = words.first
166
- end
96
+ alias_method :query, :complete
167
97
 
168
- # 根据需要的数量取出 ids
169
- ids = config.redis.sort(temp_store_key,
170
- limit: [0, limit],
171
- by: mk_score_key(type, '*'),
172
- order: 'desc')
173
- result = hmget(type, ids, sort_field: sort_field)
174
- info("{#{type} : \"#{text}\"} | Time spend: #{Time.now - tm}s")
175
- result
176
- end
177
98
  end # end class << self
178
99
 
179
- protected
180
-
181
- def self.split_pinyin(text)
182
- # Pinyin search split as pinyin again
183
- _split(PinYin.sentence(text))
184
- end
185
100
 
186
101
  private
187
102
 
188
- def self._split(text)
189
- return [] if text.blank?
190
- # return chars if disabled rmmseg
191
- return text.split('') if Search.config.disable_rmmseg
192
-
193
- algor = RMMSeg::Algorithm.new(text)
194
- words = []
195
- loop do
196
- tok = algor.next_token
197
- break if tok.nil?
198
- words << tok.text
199
- end
200
- words
201
- end
202
-
203
103
  def self.warn(msg)
204
104
  return unless Redis::Search.config.debug
205
105
  msg = "\e[33m[redis-search] #{msg}\e[0m"
@@ -3,7 +3,7 @@ class Redis
3
3
  module Search
4
4
  class Index
5
5
  attr_accessor :type, :title, :id, :score, :aliases, :exts,
6
- :condition_fields, :prefix_index_enable
6
+ :condition_fields
7
7
 
8
8
  class << self
9
9
  def redis
@@ -27,20 +27,6 @@ class Redis
27
27
  end
28
28
  end
29
29
 
30
- def split_words_for_index(title)
31
- words = Search.split(title)
32
- if Search.config.pinyin_match
33
- # covert Chinese to pinyin to as an index
34
- pinyin_full = Search.split_pinyin(title)
35
- pinyin_first = pinyin_full.collect { |p| p[0] }.join('')
36
- words += pinyin_full
37
- words << pinyin_first
38
- pinyin_full = nil
39
- pinyin_first = nil
40
- end
41
- words.uniq
42
- end
43
-
44
30
  def bm
45
31
  t1 = Time.now
46
32
  yield
@@ -58,7 +44,6 @@ class Redis
58
44
  @condition_fields = []
59
45
  @exts = []
60
46
  @aliases = []
61
- @prefix_index_enable = false
62
47
 
63
48
  # set attributes value from params
64
49
  options.keys.each do |k|
@@ -98,7 +83,7 @@ class Redis
98
83
  end
99
84
 
100
85
  # 建立前缀索引
101
- save_prefix_index if prefix_index_enable
86
+ save_prefix_index
102
87
  end
103
88
  end
104
89
 
@@ -115,7 +100,7 @@ class Redis
115
100
  redis.sadd(Search.mk_sets_key(@type, val), @id)
116
101
 
117
102
  if Search.config.pinyin_match
118
- pinyin_full = Search.split_pinyin(val.downcase)
103
+ pinyin_full = self.class.split_pinyin(val.downcase)
119
104
  pinyin_first = pinyin_full.collect { |p| p[0] }.join('')
120
105
  pinyin = pinyin_full.join('')
121
106
 
@@ -123,10 +108,6 @@ class Redis
123
108
  words << pinyin_first
124
109
 
125
110
  redis.sadd(Search.mk_sets_key(@type, pinyin), @id)
126
-
127
- pinyin_full = nil
128
- pinyin_first = nil
129
- pinyin = nil
130
111
  end
131
112
 
132
113
  words.each do |word|
@@ -140,6 +121,25 @@ class Redis
140
121
 
141
122
  redis.zadd(sorted_set_key, sorted_vals)
142
123
  end
124
+
125
+ def self.split_words_for_index(title)
126
+ words = title.split('')
127
+ if Search.config.pinyin_match
128
+ # covert Chinese to pinyin to as an index
129
+ pinyin_full = split_pinyin(title)
130
+ pinyin_first = pinyin_full.collect { |p| p[0] }.join('')
131
+ words += pinyin_full
132
+ words << pinyin_first
133
+ end
134
+ words.uniq
135
+ end
136
+
137
+ def self.split_pinyin(text)
138
+ # Pinyin search split as pinyin again
139
+ pinyin = PinYin.sentence(text)
140
+ pinyin.split(' ')
141
+ end
142
+
143
143
  end # end Index
144
144
  end
145
145
  end
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  module Search
3
- VERSION = '1.0.0.beta1'
3
+ VERSION = '1.0.0.beta2'
4
4
  end
5
5
  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: 1.0.0.beta1
4
+ version: 1.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee