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