This plugin allows boolean-queried fulltext search to be added to any Rails app with no additional dependencies and minimal setup.
- Add the gem to your Gemfile:
gem 'acts_as_indexed'- Run
bundle install.
When upgrading it is recommended to delete the index directory and allow it to be rebuilt.
Add acts_as_indexed to any models to be indexed, along with a list of the
fields to be indexed.
class Post < ActiveRecord::Base
acts_as_indexed fields: [:title, :body]
# ...
endThe fields are not limited to model fields, but can be any instance method of the current model.
class User < ActiveRecord::Base
acts_as_indexed fields: [:address, :full_name]
def full_name
[forename, surname].join(' ')
end
# ...
endAny of the configuration options in the Further
Configuration section can be added as to the
acts_as_indexed method call. these will override any defaults or global
configuration.
A proc can be assigned to the if key which determines whether a record is
added to the index.
For example, if you have a is_visible column then non-visible records can be
excluded from the index with:
acts_as_indexed fields: [:title, :body], if: proc.new { |post| post.is_visible? }To search with the most relevant matches appearing first, call the
find_with_index method on your model, passing a query as the first argument.
the optional ids_only parameter, when set to true, will return only the ids
of any matching records.
# returns array of post objects ordered by relevance.
post.find_with_index('my search query')
# pass any of the activerecord find options to the search.
post.find_with_index('my search query', { limit: 10 })
# returns array of ids ordered by relevance.
post.find_with_index('my search query', {}, { ids_only: true }) # => [12,19,33...If the relevance of the results is not important, call the with_query named
scope on your model, passing a query as an argument.
# Returns array of Post objects.
Post.with_query('my search query')
# Chain it with any number of ActiveRecord methods and named_scopes.
Post.public.with_query('my search query').find(:all, limit: 10) # return the first 10 matches which are public.The following query operators are supported:
cat dogwill find records matchingcatANDdog.cat -dogwill find records matchingcatAND NOTdogcat +mewill find records matchingcatandme, even ifmeis smaller than themin_word_size- Quoted terms are matched as phrases.
"cat dog"will find records matching the whole phrase. Quoted terms can be preceded by the NOT operator;cat -"big dog"etc. Quoted terms can include words shorter than themin_word_size. - Terms that begin with
^will match records that contain a word starting with the term.^catwill find matches containingcat,catapult,caterpillaretc. - A quoted term that begins with
^matches any phrase that begin with this phrase.^"cat d"will find records matching the whole phrases 'cat dog' andcat dinner. This type of search is useful for autocomplete inputs.
Pagination is supported via the paginate_search method whose first argument
is the search query, followed by all the standard will_paginate arguments.
Image.paginate_search('girl', page: 1, per_page: 5)Since with_query is an ActiveRecord scope, WillPaginate can be used in the normal
fashion.
Image.with_query('girl').paginate(page: 1, per_page: 5)A config block can be provided in your environment files or initializers. Example showing changing the min word size:
ActsAsIndexed.configure do |config|
config.min_word_size = 3
# More config as required...
endA full rundown of the available configuration options can be found in
lib/acts_as_indexed/configuration.rb.
Acts as Indexed is intended to provide a simple solution to full text search for modest-sized application setups. As a result it comes with some operational caveats:
- Only works with ASCII characters as does not fold/normali`e UTF-8 characters. A workaround for this is described in this Gist
- Is not multi-process safe. If two processes write to the index at the same time, the index will likely end up in an inconsistent state.
- Multiple servers (containers, Heroku Dynos, etc) will maintain their own copy of the index. These will get out of sync as write operations occur. Use of a shared filesystem prevents this.
View the rdoc documentation online at Rdoc.info.
Open a Github issue. If you have contribution you would like to make, please discuss in a Github Issue prior to submitting a pull request.
A huge thanks to all the contributors to this library. Without them many bugfixes and features wouldn't have happened.
- Douglas F Shearer - http://douglasfshearer.com
- Thomas Pomfret
- Philip Arndt
- Fernanda Lopes
- Alex Coles
- Myles Eftos
- Edward Anderson
- Florent Guilleux
- Ben Anderson
- Theron Toomey
- Uģis Ozols
- Gabriel Namiman
- Roman Samoilov
- David Turner
- Pascal Hurni
- Ryan Kopf