README.md in fuzzily-0.3.0 vs README.md in fuzzily-0.3.1

- old
+ new

@@ -9,11 +9,11 @@ > Show me photos of **Marakech** ! > > Here aresome photos of **Marrakesh**, Morroco. > Did you mean **Martanesh**, Albania, **Marakkanam**, India, or **Marasheshty**, Romania? -Blurrily finds misspelled, prefix, or partial needles in a haystack of +Fuzzily finds misspelled, prefix, or partial needles in a haystack of strings. It's a fast, [trigram](http://en.wikipedia.org/wiki/N-gram)-based, database-backed [fuzzy](http://en.wikipedia.org/wiki/Approximate_string_matching) string search/match engine for Rails. Loosely inspired from an [old blog post](http://unirec.blogspot.co.uk/2007/12/live-fuzzy-search-using-n-grams-in.html). Tested with ActiveRecord (2.3, 3.0, 3.1, 3.2, 4.0) on various Rubies (1.8.7, 1.9.2, 1.9.3, 2.0.0) and the most common adapters (SQLite3, MySQL, and PostgreSQL). @@ -43,68 +43,82 @@ - a trigram model (your search index) and its migration - the model you want to search for Create and ActiveRecord model in your app (this will be used to store a "fuzzy index" of all the models and fields you will be indexing): - class Trigram < ActiveRecord::Base - include Fuzzily::Model - end +```ruby +class Trigram < ActiveRecord::Base + include Fuzzily::Model +end +``` Create a migration for it: - class AddTrigramsModel < ActiveRecord::Migration - extend Fuzzily::Migration - end +```ruby +class AddTrigramsModel < ActiveRecord::Migration + extend Fuzzily::Migration +end +``` -Instrument your model (your searchable fields do not have to be stored, they can be dynamic methods too): +Instrument your model: - class MyStuff < ActiveRecord::Base - # assuming my_stuffs has a 'name' attribute - fuzzily_searchable :name - end +```ruby +class MyStuff < ActiveRecord::Base + # assuming my_stuffs has a 'name' attribute + fuzzily_searchable :name +end +``` Index your model (will happen automatically for new/updated records): - MyStuff.bulk_update_fuzzy_name +```ruby +MyStuff.bulk_update_fuzzy_name +``` Search! - MyStuff.find_by_fuzzy_name('Some Name', :limit => 10) - # => records +```ruby +MyStuff.find_by_fuzzy_name('Some Name', :limit => 10) +# => records +``` You can force an update on a specific record with - MyStuff.find(123).update_fuzzy_name! +```ruby +MyStuff.find(123).update_fuzzy_name! +``` ## Indexing more than one field Just list all the field you want to index, or call `fuzzily_searchable` more than once: - class MyStuff < ActiveRecord::Base - fuzzily_searchable :name_fr, :name_en - fuzzily_searchable :name_de - end +```ruby +class MyStuff < ActiveRecord::Base + fuzzily_searchable :name_fr, :name_en + fuzzily_searchable :name_de +end +``` - ## Custom name for the index model If you want or need to name your index model differently (e.g. because you already have a class called `Trigram`): - class CustomTrigram < ActiveRecord::Base - include Fuzzily::Model - end +```ruby +class CustomTrigram < ActiveRecord::Base + include Fuzzily::Model +end - class AddTrigramsModel < ActiveRecord::Migration - extend Fuzzily::Migration - trigrams_table_name = :custom_trigrams - end +class AddTrigramsModel < ActiveRecord::Migration + extend Fuzzily::Migration + trigrams_table_name = :custom_trigrams +end - class MyStuff < ActiveRecord::Base - fuzzily_searchable :name, :class_name => 'CustomTrigram' - end +class MyStuff < ActiveRecord::Base + fuzzily_searchable :name, :class_name => 'CustomTrigram' +end +``` - ## Speeding things up For large data sets (millions of rows to index), the "compatible" storage used by default will typically no longer be enough to keep the index small enough. @@ -115,11 +129,43 @@ MySQL and pgSQL. This is not the default in the gem as ActiveRecord does not suport `ENUM` columns in any version. +## UUID's +When using Rails 4 with UUID's, you will need to change the `owner_id` column type to `UUID`. + +```ruby +class AddTrigramsModel < ActiveRecord::Migration + extend Fuzzily::Migration + trigrams_owner_id_column_type = :uuid +end +``` + +## Searching virtual attributes + +Your searchable fields do not have to be stored, they can be dynamic methods +too. Just remember to add a virtual change method as well. +For instance, if you model has `first_name` and `last_name` attributes, and you +want to index a compound `name` dynamic attribute: + +```ruby +class Employee < ActiveRecord::Base + fuzzily_searchable :name + def name + "#{first_name} #{last_name}" + end + + def name_changed? + first_name_changed? || last_name_changed? + end +end +``` + + + ## License MIT licence. Quite permissive if you ask me. Copyright (c) 2013 HouseTrip Ltd. @@ -131,7 +177,7 @@ 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create a new Pull Request -Thanks to @bclennox, @fdegiuli, @nickbender, @Shanison for pointing out +Thanks to @bclennox, @fdegiuli, @nickbender, @Shanison, @rickbutton for pointing out and/or helping on various issues.