Class: SearchApi::TextCriterion
- Inherits:
-
Object
- Object
- SearchApi::TextCriterion
- Defined in:
- lib/search_api/text_criterion.rb
Overview
Utility class that implements fulltext search.
Includes some Google-like features.
Instance Attribute Summary collapse
-
#mandatory_keywords ⇒ Object
Returns the value of attribute mandatory_keywords.
-
#meta_keywords ⇒ Object
Returns the value of attribute meta_keywords.
-
#negative_keywords ⇒ Object
Returns the value of attribute negative_keywords.
-
#optional_keywords ⇒ Object
Returns the value of attribute optional_keywords.
Instance Method Summary collapse
- #condition(inFields) ⇒ Object
-
#initialize(inSearchString = '', inOptions = {}) ⇒ TextCriterion
constructor
A new instance of TextCriterion.
- #positive_keywords ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(inSearchString = '', inOptions = {}) ⇒ TextCriterion
Returns a new instance of TextCriterion.
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 |
# File 'lib/search_api/text_criterion.rb', line 21 def initialize(inSearchString='', inOptions= {}) # inOptions may contain : # :exclude => string, Regexp, or list of Strings and Regexp to exclude (strings are case insensitive) @options = inOptions @options[:exclude] = [@options[:exclude]] unless @options[:exclude].nil? || (@options[:exclude].is_a?(Enumerable) && !@options[:exclude].is_a?(String)) @options[:parse_meta?] = true if @options[:parse_meta?].nil? @meta_keywords = {} @mandatory_keywords = [] @negative_keywords = [] @optional_keywords = [] unless inSearchString.blank? currentMeta = nil splitter = / ( [-+]?\b[^ ":]+\b:? ) | ( [-+]?"[^"]*" ) /x inSearchString.gsub(/\s+/, ' ').scan(splitter).each { |keyword| keyword=(keyword[0]||keyword[1]).gsub(/"/, '') if currentMeta @meta_keywords[currentMeta] ||= [] @meta_keywords[currentMeta] << keyword currentMeta = nil else case keyword when /^-/ @negative_keywords << keyword[1..-1] unless exclude_keyword?(keyword[1..-1]) when /^\+/ @mandatory_keywords << keyword[1..-1] unless exclude_keyword?(keyword[1..-1]) when /:$/ if @options[:parse_meta?] currentMeta = keyword[0..-2] else @optional_keywords << keyword unless exclude_keyword?(keyword) end else @optional_keywords << keyword unless exclude_keyword?(keyword) end end } # if everything is excluded, look for the whole search string @optional_keywords << inSearchString if @meta_keywords.empty? && @mandatory_keywords.empty? && @negative_keywords.empty? && @optional_keywords.empty? end end |
Instance Attribute Details
#mandatory_keywords ⇒ Object
Returns the value of attribute mandatory_keywords.
17 18 19 |
# File 'lib/search_api/text_criterion.rb', line 17 def mandatory_keywords @mandatory_keywords end |
#meta_keywords ⇒ Object
Returns the value of attribute meta_keywords.
16 17 18 |
# File 'lib/search_api/text_criterion.rb', line 16 def @meta_keywords end |
#negative_keywords ⇒ Object
Returns the value of attribute negative_keywords.
18 19 20 |
# File 'lib/search_api/text_criterion.rb', line 18 def negative_keywords @negative_keywords end |
#optional_keywords ⇒ Object
Returns the value of attribute optional_keywords.
19 20 21 |
# File 'lib/search_api/text_criterion.rb', line 19 def optional_keywords @optional_keywords end |
Instance Method Details
#condition(inFields) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/search_api/text_criterion.rb', line 99 def condition(inFields) conditions = SqlFragment.new conditions << (@mandatory_keywords.inject(SqlFragment.new) { |cv, value| value = "%#{value}%" cv.and(inFields.inject(SqlFragment.new) { |cf, field| cf.or(["#{field} like ?", value]) }) }) conditions << (@negative_keywords.inject(SqlFragment.new) { |cv, value| value = "%#{value}%" cv.and(inFields.inject(SqlFragment.new) { |cf, field| cf.or(["#{field} is not null AND #{field} like ?", value]) }) }.not) conditions << (@optional_keywords.inject(SqlFragment.new) { |cv, value| value = "%#{value}%" cv.or(inFields.inject(SqlFragment.new) { |cf, field| cf.or(["#{field} like ?", value]) }) }) conditions end |
#positive_keywords ⇒ Object
95 96 97 |
# File 'lib/search_api/text_criterion.rb', line 95 def positive_keywords @mandatory_keywords + @optional_keywords end |
#to_s ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/search_api/text_criterion.rb', line 78 def to_s chunks = [] chunks += @mandatory_keywords.map { |x| (x =~ / /) ? "+\"#{x}\"" : "+#{x}" } unless @mandatory_keywords.blank? chunks += @negative_keywords.map { |x| (x =~ / /) ? "-\"#{x}\"" : "-#{x}" } unless @negative_keywords.blank? chunks += @optional_keywords.map { |x| (x =~ / /) ? "\"#{x}\"" : x.to_s } unless @optional_keywords.blank? chunks += @meta_keywords.inject([]) { |s, key_value| key, value = key_value if value.is_a?(Array) s += value.map { |x| (x =~ / /) ? "#{key}:\"#{x}\"" : "#{key}:#{x}" } else s << ((value =~ / /) ? "#{key}:\"#{value}\"" : "#{key}:#{value}") end s } if @meta_keywords chunks.join(' ') end |