Module: Redis::Search
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/redis-search/base.rb,
lib/redis-search/index.rb,
lib/redis-search/config.rb,
lib/redis-search/finder.rb,
lib/redis-search/railtie.rb,
lib/redis-search/version.rb
Overview
nodoc
Defined Under Namespace
Modules: ClassMethods Classes: Config, Index, Railtie
Constant Summary collapse
- DOT =
'.'.freeze
- VERSION =
'1.0.3'
Class Attribute Summary collapse
-
.config ⇒ Object
Returns the value of attribute config.
-
.indexed_models ⇒ Object
Returns the value of attribute indexed_models.
Class Method Summary collapse
-
.complete(type, w, options = {}) ⇒ Object
(also: query)
Use for short title search, this method is search by chars, for example Tag, User, Category …
- .configure {|@config ||= Config.new| ... } ⇒ Object
Instance Method Summary collapse
- #redis_search_alias_value(field) ⇒ Object
- #redis_search_fields_to_hash(ext_fields) ⇒ Object
- #redis_search_index_after_save ⇒ Object
- #redis_search_index_after_update ⇒ Object
- #redis_search_index_before_destroy ⇒ Object
-
#redis_search_index_create ⇒ Object
Rebuild search index with create.
- #redis_search_index_delete(titles) ⇒ Object
- #redis_search_index_need_reindex ⇒ Object
Class Attribute Details
.config ⇒ Object
Returns the value of attribute config.
4 5 6 |
# File 'lib/redis-search/config.rb', line 4 def config @config end |
.indexed_models ⇒ Object
Returns the value of attribute indexed_models.
4 5 6 |
# File 'lib/redis-search/config.rb', line 4 def indexed_models @indexed_models end |
Class Method Details
.complete(type, w, options = {}) ⇒ Object Also known as: query
Use for short title search, this method is search by chars, for example Tag, User, Category …
h3. params:
type model name
w search char
:limit result limit
:order result order
h3. usage:
-
Redis::Search.complete(“Tag”,“r”) => [“Ruby”,“Rails”, “REST”, “Redis”, “Redmine”]
-
Redis::Search.complete(“Tag”,“re”) => [“Redis”, “Redmine”]
-
Redis::Search.complete(“Tag”,“red”) => [“Redis”, “Redmine”]
-
Redis::Search.complete(“Tag”,“redi”) => [“Redis”]
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/redis-search/finder.rb', line 19 def complete(type, w, = {}) limit = [:limit] || 10 conditions = [:conditions] || [] order = [:order] || 'desc' return [] if (w.blank? && conditions.blank?) || type.blank? prefix_matchs = [] # This is not random, try to get replies < MTU size rangelen = config.complete_max_length prefix = w.downcase key = mk_complete_key(type) if start = config.redis.zrank(key, prefix) count = limit max_range = start + (rangelen * limit) - 1 range = config.redis.zrange(key, start, max_range) while prefix_matchs.length <= count start += rangelen break if !range || range.empty? range.each do |entry| minlen = [entry.length, prefix.length].min if entry[0...minlen] != prefix[0...minlen] count = prefix_matchs.count break end if entry[-1..-1] == '*' && prefix_matchs.length != count prefix_matchs << entry[0...-1] end end range = range[start..max_range] end end prefix_matchs.uniq! # 组合 words 的特别 key 名 words = prefix_matchs.collect { |w| mk_sets_key(type, w) } # 组合特别 key ,但这里不会像 query 那样放入 words, 因为在 complete 里面 words 是用 union 取的,condition_keys 和 words 应该取交集 condition_keys = [] unless conditions.blank? conditions = conditions[0] if conditions.is_a?(Array) conditions.keys.each do |c| condition_keys << mk_condition_key(type, c, conditions[c]) end end # 按词语搜索 temp_store_key = "tmpsunionstore:#{words.join('+')}" if words.length > 1 unless config.redis.exists(temp_store_key) # 将多个词语组合对比,得到并集,并存入临时区域 config.redis.sunionstore(temp_store_key, *words) # 将临时搜索设为1天后自动清除 config.redis.expire(temp_store_key, 86_400) end # 根据需要的数量取出 ids else temp_store_key = words.first end # 如果有条件,这里再次组合一下 unless condition_keys.blank? condition_keys << temp_store_key unless words.blank? temp_store_key = "tmpsinterstore:#{condition_keys.join('+')}" unless config.redis.exists(temp_store_key) config.redis.sinterstore(temp_store_key, *condition_keys) config.redis.expire(temp_store_key, 86_400) end end ids = config.redis.sort(temp_store_key, limit: [0, limit], by: mk_score_key(type, '*'), order: order) return [] if ids.blank? hmget(type, ids) end |
Instance Method Details
#redis_search_alias_value(field) ⇒ Object
26 27 28 29 30 31 32 |
# File 'lib/redis-search/base.rb', line 26 def redis_search_alias_value(field) return [] if field.blank? || field == '_was'.freeze val = (instance_eval("self.#{field}") || ''.freeze).clone return [] unless val.class.in?([String, Array]) val = val.to_s.split(',') if val.is_a?(String) val end |
#redis_search_fields_to_hash(ext_fields) ⇒ Object
18 19 20 21 22 23 24 |
# File 'lib/redis-search/base.rb', line 18 def redis_search_fields_to_hash(ext_fields) exts = {} ext_fields.each do |f| exts[f] = instance_eval(f.to_s) end exts end |
#redis_search_index_after_save ⇒ Object
106 107 108 109 110 111 |
# File 'lib/redis-search/base.rb', line 106 def redis_search_index_after_save if redis_search_index_need_reindex || new_record? redis_search_index_create end true end |
#redis_search_index_after_update ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/redis-search/base.rb', line 96 def redis_search_index_after_update if redis_search_index_need_reindex titles = redis_search_alias_value("#{[:alias_field]}_was") titles << send("#{[:title_field]}_was") redis_search_index_delete(titles) end true end |
#redis_search_index_before_destroy ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/redis-search/base.rb', line 60 def redis_search_index_before_destroy titles = redis_search_alias_value([:alias_field]) titles << send([:title_field]) redis_search_index_delete(titles) true end |
#redis_search_index_create ⇒ Object
Rebuild search index with create
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/redis-search/base.rb', line 35 def redis_search_index_create opts = { title: send([:title_field]), aliases: redis_search_alias_value([:alias_field]), id: id, exts: redis_search_fields_to_hash([:ext_fields]), type: [:class_name] || self.class.name, condition_fields: [:condition_fields], score: send([:score_field]).to_i } s = Search::Index.new(opts) s.save true end |
#redis_search_index_delete(titles) ⇒ Object
51 52 53 54 55 56 57 58 |
# File 'lib/redis-search/base.rb', line 51 def redis_search_index_delete(titles) titles.uniq! titles.each do |title| next if title.blank? Search::Index.remove(id: id, title: title, type: self.class.name) end true end |
#redis_search_index_need_reindex ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/redis-search/base.rb', line 68 def redis_search_index_need_reindex index_fields_changed = false [:ext_fields].each do |f| next if f.to_s == 'id'.freeze field_method = "#{f}_changed?" if methods.index(field_method.to_sym).nil? Redis::Search.warn("#{self.class.name} model reindex on update need #{field_method} method.") next end index_fields_changed = true if instance_eval(field_method) end begin if send("#{[:title_field]}_changed?") index_fields_changed = true end if send([:alias_field]) || send("#{[:title_field]}_changed?") index_fields_changed = true end rescue end index_fields_changed end |