README.md in mongoid_search-0.2.8 vs README.md in mongoid_search-0.3.0
- old
+ new
@@ -1,17 +1,21 @@
Mongoid Search
============
-Mongoid Search is a simple full text search implementation for Mongoid ORM.
+Mongoid Search is a simple full text search implementation for Mongoid ORM. It performs well for small data sets. If your searchable model is big (i.e. 1.000.000+ records), solr or sphinx may suit you better.
Installation
--------
In your Gemfile:
gem 'mongoid_search'
+If your project is still using mongoid 2.x.x, stick to mongoid_search 0.2.x:
+
+ gem 'mongoid_search', '~> 0.2.8'
+
Then:
bundle install
Examples
@@ -21,28 +25,28 @@
include Mongoid::Document
include Mongoid::Search
field :brand
field :name
- references_many :tags
- refereced_in :category
+ has_many :tags
+ belongs_to :category
search_in :brand, :name, :tags => :name, :category => :name
end
class Tag
include Mongoid::Document
field :name
- referenced_in :product
+ belongs_to :product
end
class Category
include Mongoid::Document
field :name
- references_many :products
+ has_many :products
end
Now when you save a product, you get a _keywords field automatically:
p = Product.new :brand => "Apple", :name => "iPhone"
@@ -50,72 +54,111 @@
p.tags << Tag.new(:name => "Awesome")
p.tags << Tag.new(:name => "Superb")
p.save
=> true
p._keywords
+ => ["amazing", "apple", "awesome", "iphone", "superb"]
Now you can run search, which will look in the _keywords field and return all matching results:
- Product.search("apple iphone").size
+ Product.full_text_search("apple iphone").size
=> 1
Note that the search is case insensitive, and accept partial searching too:
- Product.search("ipho").size
+ Product.full_text_search("ipho").size
=> 1
-
-Assuming you have a category with multiple products you can now use the following
+
+Assuming you have a category with multiple products you can use the following
code to search for 'iphone' in products cheaper than $499
- @category.products.where(:price.lt => 499).csearch('iphone').asc(:price)
+ @category.products.where(:price.lt => 499).full_text_search('iphone').asc(:price)
-In this case we have to use csearch, an alias for search, because since v2.0.0
-Mongoid defines it's own Criteria.search method.
-
Options
-------
match:
+
_:any_ - match any occurrence
+
_:all_ - match all ocurrences
+
Default is _:any_.
- search_in :brand, :name, { :tags => :name }, { :match => :any }
+ Product.full_text_search("apple motorola", match: :any).size
+ => 1
- Product.search("apple motorola").size
+ Product.full_text_search("apple motorola", match: :all).size
+ => 0
+
+allow\_empty\_search:
+
+ _true_ - will return Model.all
+
+ _false_ - will return []
+
+ Default is _false_.
+
+ Product.full_text_search("", allow_empty_search: true).size
=> 1
- search_in :brand, :name, { :tags => :name }, { :match => :all }
+relevant_search:
- Product.search("apple motorola").size
- => 0
+ _true_ - Adds relevance information to the results
-allow_empty_search:
- _true_ - match any occurrence
- _false_ - match all ocurrences
+ _false_ - No relevance information
+
Default is _false_.
- search_in :brand, :name, { :tags => :name }, { :allow_empty_search => true }
+ Product.full_text_search('amazing apple', relevant_search: true)
+ => [#<Product _id: 5016e7d16af54efe1c000001, _type: nil, brand: "Apple", name: "iPhone", attrs: nil, info: nil, category_id: nil, _keywords: ["amazing", "apple", "awesome", "iphone", "superb"], relevance: 2.0>]
- Product.search("").size
- => 1
-
-ignore_list:
- Pass in an ignore list location. Keywords in that list will be ignored.
-
- search_in :brand, :name, { :tags => :name }, { :ignore_list => Rails.root.join("config", "ignorelist.yml") }
+ Please note that relevant_search will return an Array and not a Criteria object. The search method shoud always be called in the end of the method chain.
- The list should look like:
-
- ignorelist:
- a, an, to, from, as
-
- You can include how many keywords you like.
+Initializer
+-----------
-TODO
-----
+Alternatively, you can create an initializer to setup those options:
-* Strip html with sanitize (https://github.com/rgrove/sanitize)
-* Rewrite and test relevant search
-* Move all configurations to a configuration file. Maybe /config/mongoid_search.yml.
+ Mongoid::Search.setup do |config|
+ ## Default matching type. Match :any or :all searched keywords
+ config.match = :any
+
+ ## If true, an empty search will return all objects
+ config.allow_empty_search = false
+
+ ## If true, will search with relevance information
+ config.relevant_search = false
+
+ ## Stem keywords
+ config.stem_keywords = false
+
+ ## Words to ignore
+ config.ignore_list = []
+
+ ## An array of words
+ # config.ignore_list = %w{ a an to from as }
+
+ ## Or from a file
+ # config.ignore_list = YAML.load(File.open(File.dirname(__FILE__) + '/config/ignorelist.yml'))["ignorelist"]
+
+ ## Search using regex (slower)
+ config.regex_search = true
+
+ ## Regex to search
+
+ ## Match partial words on both sides (slower)
+ config.regex = Proc.new { |query| /#{query}/ }
+
+ ## Match partial words on the beginning or in the end (slightly faster)
+ # config.regex = Proc.new { |query| /ˆ#{query}/ }
+ # config.regex = Proc.new { |query| /#{query}$/ }
+
+ # Ligatures to be replaced
+ # http://en.wikipedia.org/wiki/Typographic_ligature
+ config.ligatures = { "œ"=>"oe", "æ"=>"ae" }
+
+ # Minimum word size. Words smaller than it won't be indexed
+ config.minimum_word_size = 2
+ end