Module: Mongoid::Searchable::ClassMethods

Defined in:
lib/mongoid/searchable.rb

Instance Method Summary collapse

Instance Method Details

#clean_keywords(value) ⇒ Object

Takes a String, Numeric, Array or Hash and reduces it to a sanitized array of keywords, recursively if necessary.

value - String, Numeric, Array or Hash of data to sanitize.

Returns Array.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/mongoid/searchable.rb', line 93

def clean_keywords(value)
  words = []

  if value.is_a?(String) or value.is_a?(Numeric)
    words << value.to_s.downcase.gsub(/<\/?[^>]*>/, '').split(' ').map { |s| s.gsub(/[._:;'"`,?|+={}()!@#%^&*<>~\$\-\\\/\[\]]/, '') }.select { |s| s.length >= 2 }
  elsif value.is_a?(Array) && value.any?
    value.each do |v|
      words << clean_keywords(v)
    end
  elsif value.is_a?(Hash) && value.any?
    value.each do |k,v|
      words << clean_keywords(v)
    end
  end

  words.flatten.uniq
end

#searchable(*fields) ⇒ Object

Defines the environment for searching this document, typically called from within your model declaration.

fields - Array, mix of references to the fields

you would like to index and any *options*.

options - Hash, list of options for keyword indexing:

:as - String, field to store keywords in.
:index - Boolean, turn indexing on or off.

Example:

class Person

include Mongoid::Document
include Mongoid::Searchable
field :name
searchable :name

end

Returns nothing.



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/mongoid/searchable.rb', line 36

def searchable(*fields)
  options = { :as => :keywords, :index => true }.merge(fields.extract_options!)

  self.keywords_field = options[:as].to_sym
  self.searchable_fields = fields.map(&:to_s)

  field keywords_field
  index :keywords if options[:index]

  before_save :build_keywords
end

#text_search(query, options = {}) ⇒ Object

Search for documents matching your query, given the previously defined keyword fields.

query - Integer, String, Array, Hash representing the query

you wish to perform. This will be reduced to a string, sanitized
and then split into keywords used for matching.

options - Hash, containing options used for the query:

:match - Symbol, :all or :any, how to match results.
:exact - Boolean, require exact word match (or not).

Returns Mongoid::Criteria.



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
# File 'lib/mongoid/searchable.rb', line 61

def text_search(query, options={})
  keywords = clean_keywords(query)
  options[:match] ||= :all
  options[:exact] ||= false

  if options[:exact]
    match = keywords
  else
    match = keywords.collect{|k| /#{Regexp.escape(k)}/ }
  end

  raise "Please define one or more fields as searchable before attempting to search." if keywords_field.nil? or searchable_fields.nil?

  if keywords.any?
    if options[:match].to_sym == :all
      all_in(keywords_field.to_sym => match)
    elsif options[:match].to_sym == :any
      any_in(keywords_field.to_sym => match)
    else
      raise "Please specify either :all or :any to match."
    end
  else
    where()
  end
end