Module: SearchDo::ClassMethods

Defined in:
lib/search_do.rb

Constant Summary collapse

VALID_FULLTEXT_OPTIONS =
[:limit, :offset, :order, :attributes, :raw_matches, :find, :count]

Instance Method Summary collapse

Instance Method Details

#acts_as_searchable(options = {}) ⇒ Object

Configuration options

  • searchable_fields - Fields to provide searching and indexing for (default: ‘body’)

  • attributes - Additional attributes to store in Hyper Estraier with the appropriate method supplying the value

  • if_changed - Extra list of attributes to add to the list of attributes that trigger an index update when changed

Examples:

acts_as_searchable :attributes => { :title => nil, :blog => :blog_title }, :searchable_fields => [ :title, :body ]

This would store the return value of the title method in the title attribute and the return value of the blog_title method in the blog attribute. The contents of the title and body columns would end up being indexed for searching.

Attribute naming

Attributes that match the reserved names of the Hyper Estraier system attributes are mapped automatically. This is something to keep in mind for custom ordering options or additional query constraints in fulltext_search For a list of these attributes see EstraierPure::SYSTEM_ATTRIBUTES or visit:

http://hyperestraier.sourceforge.net/uguide-en.html#attributes

From the example above:

Model.fulltext_search('query', :order => '@title STRA')               # Returns results ordered by title in ascending order
Model.fulltext_search('query', :attributes => 'blog STREQ poocs.net') # Returns results with a blog attribute of 'poocs.net'


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/search_do.rb', line 116

def acts_as_searchable(options = {})
  return if self.included_modules.include?(SearchDo::InstanceMethods)

  cattr_accessor :search_indexer, :search_backend

  self.search_indexer = SearchDo::Indexer.new(self, configurations).tap do |idx|
    idx.searchable_fields   = options[:searchable_fields] || [ :body ]
    idx.attributes_to_store = options[:attributes] || {}
    idx.if_changed          = options[:if_changed] || []
  end

  if !options[:ignore_timestamp] && self.record_timestamps
    search_indexer.record_timestamps!
  end

  unless options[:auto_update] == false
    search_indexer.add_callbacks!
  end

  include SearchDo::InstanceMethods
  include SearchDo::DirtyTracking

  connect_backend(configurations)
end

#clear_index!Object

Clear all entries from index



234
235
236
# File 'lib/search_do.rb', line 234

def clear_index!
  search_backend.clear_index!
end

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



202
203
204
# File 'lib/search_do.rb', line 202

def count_fulltext(query, options={})
  search_backend.count(query, options)
end

#find_fulltext(query, options = {}, with_mdate_desc_order = true) ⇒ Object

this methods is NOT compat with original AAS FIXME is see no need for this method



208
209
210
211
212
213
# File 'lib/search_do.rb', line 208

def find_fulltext(query, options={}, with_mdate_desc_order=true)
  fulltext_option = {}
  fulltext_option[:order] = :updated_at if with_mdate_desc_order
  ids = matched_ids(query, fulltext_option)
  find_by_ids_scope(ids, options)
end

#fulltext_search(query = "", options = {}) ⇒ Object

Perform a fulltext search against the Hyper Estraier index.

Adds snippet (text that surround the place where the word was found) to results if the model responds to snippet=

Options taken:

  • limit - Maximum number of records to retrieve (default: 100)

  • offset - Number of records to skip (default: 0)

  • order - Hyper Estraier expression to sort the results (example: @title STRA, default: ordering by score)

  • attributes - String to append to Hyper Estraier search query

  • raw_matches - Returns raw Hyper Estraier documents instead of instantiated AR objects

  • find - Options to pass on to the ActiveRecord::Base#find call

  • count - Set this to true if you’re using fulltext_search in conjunction with ActionController::Pagination to return the number of matches only

Examples:

Article.fulltext_search("biscuits AND gravy")
Article.fulltext_search("biscuits AND gravy", :limit => 15, :offset => 14)
Article.fulltext_search("biscuits AND gravy", :attributes => "tag STRINC food")
Article.fulltext_search("biscuits AND gravy", :attributes => {:user_id=>1})
Article.fulltext_search("biscuits AND gravy", :attributes => {:tag=>'food'})
Article.fulltext_search("biscuits AND gravy", :attributes => ["tag STRINC food", "@title STRBW Biscuit"])
Article.fulltext_search("biscuits AND gravy", :order => "created_at DESC")
Article.fulltext_search("biscuits AND gravy", :raw_matches => true)
Article.fulltext_search("biscuits AND gravy", :find => { :order => :title, :include => :comments })

Consult the Hyper Estraier documentation on proper query syntax:

http://hyperestraier.sourceforge.net/uguide-en.html#searchcond


170
171
172
173
174
175
176
177
178
179
180
# File 'lib/search_do.rb', line 170

def fulltext_search(query = "", options = {})
  find_options = options[:find] || {}
  [ :limit, :offset ].each { |k| find_options.delete(k) } unless find_options.blank?

  ids_and_raw = matched_ids_and_raw(query, options)
  ids = ids_and_raw.map{|id,raw| id}

  results = find_by_ids_scope(ids, find_options)
  add_snippets(results,ids_and_raw) unless query.blank?
  results
end

#matched_ids(query = "", options = {}) ⇒ Object



220
221
222
# File 'lib/search_do.rb', line 220

def matched_ids(query = "", options = {})
  matched_ids_and_raw(query,options).map{|id,raw|id}
end

#matched_ids_and_raw(query = "", options = {}) ⇒ Object

[1,Raw],,…


216
217
218
# File 'lib/search_do.rb', line 216

def matched_ids_and_raw(query = "", options = {})
  search_backend.search_all_ids_and_raw(query, options)
end

#matched_raw(query = "", options = {}) ⇒ Object Also known as: raw_matches



224
225
226
# File 'lib/search_do.rb', line 224

def matched_raw(query = "", options = {})
  matched_ids_and_raw(query,options).map{|id,raw|raw}
end

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



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/search_do.rb', line 182

def paginate_by_fulltext_search(query, options={})
  WillPaginate::Collection.create(*wp_parse_options(options)) do |pager|
    #transform acts_as_searchable options to will_paginate options
    page,per_page,total = wp_parse_options(options)
    options[:limit]=per_page
    options[:offset]=(page.to_i-1)*per_page
    options.delete(:page)#acts_as cannot read this...
    options.delete(:per_page)#acts_as cannot read this...

    #find results
    pager.replace fulltext_search(query,options)

    #total items
    #replace sets total if it can calculate by them itself
    unless pager.total_entries
      pager.total_entries = count_fulltext(query, :attributes=>options[:attributes]||{})
    end
  end
end

#raw_fulltext_indexObject



229
230
231
# File 'lib/search_do.rb', line 229

def raw_fulltext_index
  search_backend.index
end

#reindex!Object

Peform a full re-index of the model data for this model



239
240
241
# File 'lib/search_do.rb', line 239

def reindex!
  find(:all).each { |r| r.update_index(true) }
end