mongoid_search 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eaeb19566825291c03bd018b9013d0c06a8b01c4
4
+ data.tar.gz: 2b930fec009de9031350c4b7fbc658c928224eed
5
+ SHA512:
6
+ metadata.gz: 3111148a9311c26712eb3bbbccf7ec3c8c8d1db7283ac3e8435244558a16d157cdc22e039715bef5192234dc1a1ca80308d2a3805f7a8479eb27d8de4f689b92
7
+ data.tar.gz: 9ed30923429cba88f73916057671a598ecc0589ea67016817b74ffb68b4721ded77c58c07af285914dcad92998c70b69c5a5f64d81fc53670a15ef73c6e3e9f4
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Mauricio Zaffari
1
+ Copyright (c) 2009 Mauricio Zaffari, 2013 Semenyuk Dmitriy (additions)
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -26,11 +26,12 @@ Examples
26
26
  include Mongoid::Search
27
27
  field :brand
28
28
  field :name
29
+ field :info, :type => Hash
29
30
 
30
31
  has_many :tags
31
32
  belongs_to :category
32
33
 
33
- search_in :brand, :name, :tags => :name, :category => :name
34
+ search_in :brand, :name, :tags => :name, :category => :name, :info => [:summary, :description]
34
35
  end
35
36
 
36
37
  class Tag
@@ -49,14 +50,14 @@ Examples
49
50
 
50
51
  Now when you save a product, you get a _keywords field automatically:
51
52
 
52
- p = Product.new :brand => "Apple", :name => "iPhone"
53
+ p = Product.new :brand => "Apple", :name => "iPhone", :info => {:summary => "Info-summary", :description => "Info-description"}
53
54
  p.tags << Tag.new(:name => "Amazing")
54
55
  p.tags << Tag.new(:name => "Awesome")
55
56
  p.tags << Tag.new(:name => "Superb")
56
57
  p.save
57
58
  => true
58
59
  p._keywords
59
- => ["amazing", "apple", "awesome", "iphone", "superb"]
60
+ => ["amazing", "apple", "awesome", "iphone", "superb", "Info-summary", "Info-description"]
60
61
 
61
62
  Now you can run search, which will look in the _keywords field and return all matching results:
62
63
 
@@ -73,6 +74,9 @@ code to search for 'iphone' in products cheaper than $499
73
74
 
74
75
  @category.products.where(:price.lt => 499).full_text_search('iphone').asc(:price)
75
76
 
77
+ To index or reindex all existing records, run this rake task
78
+
79
+ $ rake mongoid_search:index
76
80
 
77
81
  Options
78
82
  -------
@@ -113,7 +117,7 @@ relevant_search:
113
117
  Product.full_text_search('amazing apple', relevant_search: true)
114
118
  => [#<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>]
115
119
 
116
- 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.
120
+ Please note that relevant_search will return an Array and not a Criteria object. The search method should always be called in the end of the method chain.
117
121
 
118
122
  Initializer
119
123
  -----------
@@ -155,7 +159,7 @@ Alternatively, you can create an initializer to setup those options:
155
159
  config.regex = Proc.new { |query| /#{query}/ }
156
160
 
157
161
  ## Match partial words on the beginning or in the end (slightly faster)
158
- # config.regex = Proc.new { |query| /ˆ#{query}/ }
162
+ # config.regex = Proc.new { |query| /^#{query}/ }
159
163
  # config.regex = Proc.new { |query| /#{query}$/ }
160
164
 
161
165
  # Ligatures to be replaced
@@ -165,4 +169,3 @@ Alternatively, you can create an initializer to setup those options:
165
169
  # Minimum word size. Words smaller than it won't be indexed
166
170
  config.minimum_word_size = 2
167
171
  end
168
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.3
@@ -1,8 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'mongoid_search/railtie' if defined?(Rails)
4
3
  require 'mongoid_search/mongoid_search'
5
4
 
5
+ if defined?(Rails)
6
+ require 'mongoid_search/railtie'
7
+ end
8
+
6
9
  module Mongoid::Search
7
10
  ## Default matching type. Match :any or :all searched keywords
8
11
  mattr_accessor :match
@@ -45,7 +48,7 @@ module Mongoid::Search
45
48
  @@regex = Proc.new { |query| /#{query}/ }
46
49
 
47
50
  ## Match partial words on the beginning or in the end (slightly faster)
48
- # @@regex = Proc.new { |query| /ˆ#{query}/ }
51
+ # @@regex = Proc.new { |query| /^#{query}/ }
49
52
  # @@regex = Proc.new { |query| /#{query}$/ }
50
53
 
51
54
  # Ligatures to be replaced
@@ -63,4 +66,4 @@ module Mongoid::Search
63
66
  end
64
67
 
65
68
  require 'mongoid_search/util'
66
- require 'mongoid_search/log'
69
+ require 'mongoid_search/log'
@@ -1,11 +1,10 @@
1
1
  module Mongoid::Search
2
- def self.included(base)
3
- base.send(:cattr_accessor, :search_fields)
4
-
5
- base.extend ClassMethods
2
+ extend ActiveSupport::Concern
6
3
 
4
+ included do
5
+ cattr_accessor :search_fields
7
6
  @@classes ||= []
8
- @@classes << base
7
+ @@classes << self
9
8
  end
10
9
 
11
10
  def self.classes
@@ -15,7 +14,7 @@ module Mongoid::Search
15
14
  module ClassMethods #:nodoc:
16
15
  # Set a field or a number of fields as sources for search
17
16
  def search_in(*args)
18
- args, options = args_and_options(args)
17
+ args, _options = args_and_options(args)
19
18
  self.search_fields = (self.search_fields || []).concat args
20
19
 
21
20
  field :_keywords, :type => Array
@@ -27,6 +26,8 @@ module Mongoid::Search
27
26
 
28
27
  def full_text_search(query, options={})
29
28
  options = extract_options(options)
29
+ attr_accessor :relevance if options[:relevant_search].eql? true
30
+
30
31
  return (options[:allow_empty_search] ? criteria.all : []) if query.blank?
31
32
 
32
33
  if options[:relevant_search]
@@ -47,6 +48,7 @@ module Mongoid::Search
47
48
  end
48
49
 
49
50
  private
51
+
50
52
  def query(keywords, options)
51
53
  keywords_hash = keywords.map do |kw|
52
54
  kw = Mongoid::Search.regex.call(kw) if Mongoid::Search.regex_search
@@ -58,9 +60,9 @@ module Mongoid::Search
58
60
 
59
61
  def args_and_options(args)
60
62
  options = args.last.is_a?(Hash) &&
61
- [:match,
62
- :allow_empty_search,
63
- :relevant_search].include?(args.last.keys.first) ? args.pop : {}
63
+ [:match,
64
+ :allow_empty_search,
65
+ :relevant_search].include?(args.last.keys.first) ? args.pop : {}
64
66
 
65
67
  [args, extract_options(options)]
66
68
  end
@@ -93,25 +95,25 @@ module Mongoid::Search
93
95
  keywords = Mongoid::Search::Util.normalize_keywords(query)
94
96
 
95
97
  map = %Q{
96
- function() {
97
- var entries = 0;
98
- for(i in keywords) {
99
- for(j in this._keywords) {
100
- if(this._keywords[j] == keywords[i]) {
101
- entries++;
98
+ function() {
99
+ var entries = 0;
100
+ for(i in keywords) {
101
+ for(j in this._keywords) {
102
+ if(this._keywords[j] == keywords[i]) {
103
+ entries++;
104
+ }
102
105
  }
103
106
  }
107
+ if(entries > 0) {
108
+ emit(this, entries);
109
+ }
104
110
  }
105
- if(entries > 0) {
106
- emit(this, entries);
107
- }
108
- }
109
111
  }
110
112
 
111
113
  reduce = %Q{
112
- function(key, values) {
113
- return(values);
114
- }
114
+ function(key, values) {
115
+ return(values);
116
+ }
115
117
  }
116
118
 
117
119
  query(keywords, options).map_reduce(map, reduce).scope(:keywords => keywords).out(:inline => 1)
@@ -122,7 +124,6 @@ module Mongoid::Search
122
124
  update_attribute(:_keywords, set_keywords)
123
125
  end
124
126
 
125
- private
126
127
  def set_keywords
127
128
  self._keywords = Mongoid::Search::Util.keywords(self, self.search_fields).
128
129
  flatten.reject{|k| k.nil? || k.empty?}.uniq.sort
@@ -1,10 +1,7 @@
1
- require 'mongoid_search'
2
- require 'rails'
3
-
4
1
  module Mongoid::Search
5
2
  class Railtie < Rails::Railtie
6
3
  rake_tasks do
7
- Dir[File.join(File.dirname(__FILE__), '../../tasks/*.rake')].each { |f| load f }
4
+ Dir[File.join(File.dirname(__FILE__), 'tasks/*.rake')].each { |f| load f }
8
5
  end
9
6
  end
10
- end
7
+ end
@@ -0,0 +1,16 @@
1
+ namespace :mongoid_search do
2
+ desc 'Goes through all documents with search enabled and indexes the keywords.'
3
+ task :index => :environment do
4
+ ::Rails.application.eager_load!
5
+ if Mongoid::Search.classes.blank?
6
+ Mongoid::Search::Log.log "No model to index keywords.\n"
7
+ else
8
+ Mongoid::Search.classes.each do |klass|
9
+ Mongoid::Search::Log.silent = ENV['SILENT']
10
+ Mongoid::Search::Log.log "\nIndexing documents for #{klass.name}:\n"
11
+ klass.index_keywords!
12
+ end
13
+ Mongoid::Search::Log.log "\n\nDone.\n"
14
+ end
15
+ end
16
+ end
@@ -42,7 +42,7 @@ module Mongoid::Search::Util
42
42
  downcase.
43
43
  to_s.
44
44
  gsub(/[._:;'"`,?|+={}()!@#%^&*<>~\$\-\\\/\[\]]/, ' '). # strip punctuation
45
- gsub(/[^[:alnum:]\s]/,''). # strip accents
45
+ gsub(/[^\s\p{Alnum}]/,''). # strip accents
46
46
  gsub(/[#{ligatures.keys.join("")}]/) {|c| ligatures[c]}.
47
47
  split(' ').
48
48
  reject { |word| word.size < Mongoid::Search.minimum_word_size }
@@ -1,5 +1,7 @@
1
1
  class Category
2
2
  include Mongoid::Document
3
+ include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
4
+
3
5
  field :name, localize: true
4
6
  field :description
5
7
 
@@ -1,6 +1,8 @@
1
1
  class Product
2
2
  include Mongoid::Document
3
3
  include Mongoid::Search
4
+ include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
5
+
4
6
  field :brand
5
7
  field :name
6
8
  field :attrs, :type => Array
@@ -1,8 +1,9 @@
1
1
  class Subproduct
2
2
  include Mongoid::Document
3
+ include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
3
4
 
4
5
  field :brand
5
6
  field :name
6
7
 
7
- belongs_to :product, :inverse_of => :subproducts
8
+ embedded_in :product, :inverse_of => :subproducts
8
9
  end
data/spec/models/tag.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  class Tag
2
2
  include Mongoid::Document
3
3
  include Mongoid::Search
4
+ include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
4
5
 
5
6
  field :name
6
7
 
@@ -18,19 +18,19 @@ describe Mongoid::Search do
18
18
  Mongoid::Search.ignore_list = nil
19
19
  Mongoid::Search.stem_proc = @default_proc
20
20
  @product = Product.create :brand => "Apple",
21
- :name => "iPhone",
22
- :tags => (@tags = ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) }),
23
- :category => Category.new(:name => "Mobile", :description => "Reviews"),
24
- :subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")],
25
- :info => { :summary => "Info-summary",
26
- :description => "Info-description"}
21
+ :name => "iPhone",
22
+ :tags => (@tags = ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) }),
23
+ :category => Category.new(:name => "Mobile", :description => "Reviews"),
24
+ :subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")],
25
+ :info => { :summary => "Info-summary",
26
+ :description => "Info-description"}
27
27
  end
28
28
 
29
29
  describe "Serialized hash fields" do
30
30
  context "when the hash is populated" do
31
31
  it "should return the product" do
32
- Product.full_text_search("Info-summary").first.should eq @product
33
- Product.full_text_search("Info-description").first.should eq @product
32
+ expect(Product.full_text_search("Info-summary").first).to eq @product
33
+ expect(Product.full_text_search("Info-description").first).to eq @product
34
34
  end
35
35
  end
36
36
 
@@ -41,8 +41,8 @@ describe Mongoid::Search do
41
41
  end
42
42
 
43
43
  it "should not return the product" do
44
- Product.full_text_search("Info-description").size.should eq 0
45
- Product.full_text_search("Info-summary").size.should eq 0
44
+ expect(Product.full_text_search("Info-description").size).to eq 0
45
+ expect(Product.full_text_search("Info-summary").size).to eq 0
46
46
  end
47
47
  end
48
48
  end
@@ -52,49 +52,50 @@ describe Mongoid::Search do
52
52
  Mongoid::Search.stem_keywords = false
53
53
  Mongoid::Search.ignore_list = nil
54
54
  @product = Product.create :brand => "Эльбрус",
55
- :name => "Процессор",
56
- :tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
57
- :category => Category.new(:name => "процессоры"),
58
- :subproducts => []
55
+ :name => "Процессор",
56
+ :tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
57
+ :category => Category.new(:name => "процессоры"),
58
+ :subproducts => []
59
59
  end
60
60
 
61
61
  it "should leave utf8 characters" do
62
- @product._keywords.should == ["amazing", "awesome", "ole", "процессор", "процессоры", "эльбрус"]
62
+ expect(@product._keywords).to eq ["amazing", "awesome", "ole", "процессор", "процессоры", "эльбрус"]
63
63
  end
64
64
 
65
65
  it "should return results in search when case doesn't match" do
66
- Product.full_text_search("ЭЛЬБРУС").size.should == 1
66
+ expect(Product.full_text_search("ЭЛЬБРУС").size).to eq 1
67
67
  end
68
68
  end
69
69
 
70
70
  context "when references are nil" do
71
71
  context "when instance is being created" do
72
72
  it "should not complain about method missing" do
73
- lambda { Product.create! }.should_not raise_error
73
+ expect { Product.create! }.not_to raise_error
74
74
  end
75
75
  end
76
76
 
77
- subject { Product.create :brand => "Apple", :name => "iPhone" }
78
-
79
- its(:_keywords) { should == ["apple", "iphone"] }
77
+ it 'should validate keywords' do
78
+ product = Product.create :brand => "Apple", :name => "iPhone"
79
+ expect(product._keywords).to eq(["apple", "iphone"])
80
+ end
80
81
  end
81
82
 
82
83
 
83
84
  it "should set the _keywords field for array fields also" do
84
85
  @product.attrs = ['lightweight', 'plastic', :red]
85
86
  @product.save!
86
- @product._keywords.should include 'lightweight', 'plastic', 'red'
87
+ expect(@product._keywords).to include 'lightweight', 'plastic', 'red'
87
88
  end
88
89
 
89
90
  it "should inherit _keywords field and build upon" do
90
91
  variant = Variant.create :brand => "Apple",
91
- :name => "iPhone",
92
- :tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
93
- :category => Category.new(:name => "Mobile"),
94
- :subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")],
95
- :color => :white
96
- variant._keywords.should include 'white'
97
- Variant.full_text_search(:name => 'Apple', :color => :white).should eq [variant]
92
+ :name => "iPhone",
93
+ :tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
94
+ :category => Category.new(:name => "Mobile"),
95
+ :subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")],
96
+ :color => :white
97
+ expect(variant._keywords).to include 'white'
98
+ expect(Variant.full_text_search(:name => 'Apple', :color => :white)).to eq [variant]
98
99
  end
99
100
 
100
101
  it "should expand the ligature to ease searching" do
@@ -102,115 +103,115 @@ describe Mongoid::Search do
102
103
  variant1 = Variant.create :tags => ["œuvre"].map {|tag| Tag.new(:name => tag)}
103
104
  variant2 = Variant.create :tags => ["æquo"].map {|tag| Tag.new(:name => tag)}
104
105
 
105
- Variant.full_text_search("œuvre").should eq [variant1]
106
- Variant.full_text_search("oeuvre").should eq [variant1]
107
- Variant.full_text_search("æquo").should eq [variant2]
108
- Variant.full_text_search("aequo").should eq [variant2]
106
+ expect(Variant.full_text_search("œuvre")).to eq [variant1]
107
+ expect(Variant.full_text_search("oeuvre")).to eq [variant1]
108
+ expect(Variant.full_text_search("æquo")).to eq [variant2]
109
+ expect(Variant.full_text_search("aequo")).to eq [variant2]
109
110
  end
110
111
 
111
112
  it "should set the _keywords field with stemmed words if stem is enabled" do
112
113
  Mongoid::Search.stem_keywords = true
113
114
  @product.save!
114
- @product._keywords.sort.should == ["amaz", "appl", "awesom", "craddl", "iphon", "mobil", "review", "ol", "info", "descript", "summari"].sort
115
+ expect(@product._keywords.sort).to eq ["amaz", "appl", "awesom", "craddl", "iphon", "mobil", "review", "ol", "info", "descript", "summari"].sort
115
116
  end
116
117
 
117
118
  it "should set the _keywords field with custom stemmed words if stem is enabled with a custom lambda" do
118
119
  Mongoid::Search.stem_keywords = true
119
120
  Mongoid::Search.stem_proc = Proc.new { |word| word.upcase }
120
121
  @product.save!
121
- @product._keywords.sort.should == ["AMAZING", "APPLE", "AWESOME", "CRADDLE", "DESCRIPTION", "INFO", "IPHONE", "MOBILE", "OLE", "REVIEWS", "SUMMARY"]
122
+ expect(@product._keywords.sort).to eq ["AMAZING", "APPLE", "AWESOME", "CRADDLE", "DESCRIPTION", "INFO", "IPHONE", "MOBILE", "OLE", "REVIEWS", "SUMMARY"]
122
123
  end
123
124
 
124
125
  it "should ignore keywords in an ignore list" do
125
126
  Mongoid::Search.ignore_list = YAML.load(File.open(File.dirname(__FILE__) + '/config/ignorelist.yml'))["ignorelist"]
126
127
  @product.save!
127
- @product._keywords.sort.should == ["apple", "craddle", "iphone", "mobile", "reviews", "ole", "info", "description", "summary"].sort
128
+ expect(@product._keywords.sort).to eq ["apple", "craddle", "iphone", "mobile", "reviews", "ole", "info", "description", "summary"].sort
128
129
  end
129
130
 
130
- it "should incorporate numbers as keywords" do
131
- @product = Product.create :brand => "Ford",
132
- :name => "T 1908",
133
- :tags => ["Amazing", "First", "Car"].map { |tag| Tag.new(:name => tag) },
134
- :category => Category.new(:name => "Vehicle")
131
+ it "should incorporate numbers as keywords" do
132
+ @product = Product.create :brand => "Ford",
133
+ :name => "T 1908",
134
+ :tags => ["Amazing", "First", "Car"].map { |tag| Tag.new(:name => tag) },
135
+ :category => Category.new(:name => "Vehicle")
135
136
 
136
- @product.save!
137
- @product._keywords.should == ["1908", "amazing", "car", "first", "ford", "vehicle"]
138
- end
137
+ @product.save!
138
+ expect(@product._keywords).to eq ["1908", "amazing", "car", "first", "ford", "vehicle"]
139
+ end
139
140
 
140
141
  it "should return results in search" do
141
- Product.full_text_search("apple").size.should == 1
142
+ expect(Product.full_text_search("apple").size).to eq 1
142
143
  end
143
144
 
144
145
  it "should return results in search for dynamic attribute" do
145
146
  @product[:outlet] = "online shop"
146
147
  @product.save!
147
- Product.full_text_search("online").size.should == 1
148
+ expect(Product.full_text_search("online").size).to eq 1
148
149
  end
149
150
 
150
151
  it "should return results in search even searching a accented word" do
151
- Product.full_text_search("Ole").size.should == 1
152
- Product.full_text_search("Olé").size.should == 1
152
+ expect(Product.full_text_search("Ole").size).to eq 1
153
+ expect(Product.full_text_search("Olé").size).to eq 1
153
154
  end
154
155
 
155
156
  it "should return results in search even if the case doesn't match" do
156
- Product.full_text_search("oLe").size.should == 1
157
+ expect(Product.full_text_search("oLe").size).to eq 1
157
158
  end
158
159
 
159
160
  it "should return results in search with a partial word by default" do
160
- Product.full_text_search("iph").size.should == 1
161
+ expect(Product.full_text_search("iph").size).to eq 1
161
162
  end
162
163
 
163
164
  it "should return results for any matching word with default search" do
164
- Product.full_text_search("apple motorola").size.should == 1
165
+ expect(Product.full_text_search("apple motorola").size).to eq 1
165
166
  end
166
167
 
167
168
  it "should not return results when all words do not match, if using :match => :all" do
168
169
  Mongoid::Search.match = :all
169
- Product.full_text_search("apple motorola").size.should == 0
170
+ expect(Product.full_text_search("apple motorola").size).to eq 0
170
171
  end
171
172
 
172
173
  it "should return results for any matching word, using :match => :all, passing :match => :any to .full_text_search" do
173
174
  Mongoid::Search.match = :all
174
- Product.full_text_search("apple motorola", :match => :any).size.should == 1
175
+ expect(Product.full_text_search("apple motorola", :match => :any).size).to eq 1
175
176
  end
176
177
 
177
178
  it "should not return results when all words do not match, passing :match => :all to .full_text_search" do
178
- Product.full_text_search("apple motorola", :match => :all).size.should == 0
179
+ expect(Product.full_text_search("apple motorola", :match => :all).size).to eq 0
179
180
  end
180
181
 
181
182
  it "should return no results when a blank search is made" do
182
183
  Mongoid::Search.allow_empty_search = false
183
- Product.full_text_search("").size.should == 0
184
+ expect(Product.full_text_search("").size).to eq 0
184
185
  end
185
186
 
186
187
  it "should return results when a blank search is made when :allow_empty_search is true" do
187
188
  Mongoid::Search.allow_empty_search = true
188
- Product.full_text_search("").size.should == 1
189
+ expect(Product.full_text_search("").size).to eq 1
189
190
  end
190
191
 
191
192
  it "should search for embedded documents" do
192
- Product.full_text_search("craddle").size.should == 1
193
+ expect(Product.full_text_search("craddle").size).to eq 1
193
194
  end
194
195
 
195
196
  it "should search for reference documents" do
196
- Product.full_text_search("reviews").size.should == 1
197
+ expect(Product.full_text_search("reviews").size).to eq 1
197
198
  end
198
199
 
199
200
  it 'should work in a chainable fashion' do
200
- @product.category.products.where(:brand => 'Apple').full_text_search('apple').size.should == 1
201
- @product.category.products.full_text_search('craddle').where(:brand => 'Apple').size.should == 1
201
+ expect(@product.category.products.where(:brand => 'Apple').full_text_search('apple').size).to eq 1
202
+ expect(@product.category.products.full_text_search('craddle').where(:brand => 'Apple').size).to eq 1
202
203
  end
203
204
 
204
205
  it 'should return the classes that include the search module' do
205
- Mongoid::Search.classes.should == [Product, Tag]
206
+ expect(Mongoid::Search.classes).to eq [Product, Tag]
206
207
  end
207
208
 
208
209
  it 'should have a method to index keywords' do
209
- @product.index_keywords!.should == true
210
+ expect(@product.index_keywords!).to eq true
210
211
  end
211
212
 
212
213
  it 'should have a class method to index all documents keywords' do
213
- Product.index_keywords!.should_not include(false)
214
+ expect(Product.index_keywords!).not_to include(false)
214
215
  end
215
216
 
216
217
  context "when regex search is false" do
@@ -219,11 +220,60 @@ describe Mongoid::Search do
219
220
  end
220
221
 
221
222
  it "should not return results in search with a partial word if not using regex search" do
222
- Product.full_text_search("iph").size.should == 0
223
+ expect(Product.full_text_search("iph").size).to eq 0
223
224
  end
224
225
 
225
226
  it "should return results in search with a full word if not using regex search" do
226
- Product.full_text_search("iphone").size.should == 1
227
+ expect(Product.full_text_search("iphone").size).to eq 1
228
+ end
229
+ end
230
+
231
+ context "when regex search is true" do
232
+
233
+ before do
234
+ Mongoid::Search.regex_search = true
235
+ end
236
+
237
+ after do
238
+ Mongoid::Search.regex_search = false
239
+ end
240
+
241
+ it "should not return results in search with a partial word if using regex search" do
242
+ expect(Product.full_text_search("iph").size).to eq 1
243
+ end
244
+
245
+ it "should return results in search with a full word if using regex search" do
246
+ expect(Product.full_text_search("iphone").size).to eq 1
247
+ end
248
+
249
+ context 'Match partial words on the beginning' do
250
+
251
+ before do
252
+ Mongoid::Search.regex = Proc.new { |query| /^#{query}/ }
253
+ end
254
+
255
+ it "should return results in search which starts with query string" do
256
+ expect(Product.full_text_search("iphone").size).to eq 1
257
+ end
258
+
259
+ it "should not return results in search which does not start with query string" do
260
+ expect(Product.full_text_search("phone").size).to eq 0
261
+ end
262
+ end
263
+
264
+ context 'Match partial words on the end' do
265
+
266
+ before do
267
+ Mongoid::Search.regex = Proc.new { |query| /#{query}$/ }
268
+ end
269
+
270
+ it "should return results in search which ends with query string" do
271
+ expect(Product.full_text_search("phone").size).to eq 1
272
+ end
273
+
274
+ it "should not return results in search which does not end with query string" do
275
+ expect(Product.full_text_search("phon").size).to eq 0
276
+ end
227
277
  end
228
278
  end
229
279
 
@@ -234,40 +284,61 @@ describe Mongoid::Search do
234
284
  end
235
285
 
236
286
  it "should return results ordered by relevance and with correct ids" do
237
- Product.full_text_search('apple imac').map(&:_id).should == [@imac._id, @product._id]
287
+ expect(Product.full_text_search('apple imac').map(&:_id)).to eq [@imac._id, @product._id]
238
288
  end
239
289
 
240
290
  it "results should be recognized as persisted objects" do
241
- Product.full_text_search('apple imac').map(&:persisted?).should_not include false
291
+ expect(Product.full_text_search('apple imac').map(&:persisted?)).not_to include false
242
292
  end
243
293
 
244
294
  it "should include relevance information" do
245
- Product.full_text_search('apple imac').map(&:relevance).should == [2, 1]
295
+ expect(Product.full_text_search('apple imac').map(&:relevance)).to eq [2, 1]
246
296
  end
247
297
  end
248
298
 
249
299
  context "when using methods for keywords" do
250
300
  it "should set the _keywords from methods" do
251
- @tags.first._keywords.should include "amazing"
301
+ expect(@tags.first._keywords).to include "amazing"
252
302
  end
253
303
  end
254
304
 
255
305
  context "when using deeply nested fields for keywords" do
256
306
  context "when explicitly calling set_keywords" do
257
- it "should set the _keywords from parent" do
258
- @tags.first.send(:set_keywords)
259
- @tags.first._keywords.should == ["amazing", "description", "info", "iphone", "mobile", "reviews", "summary"]
260
- end
307
+ it "should set the _keywords from parent" do
308
+ @tags.first.send(:set_keywords)
309
+ expect(@tags.first._keywords).to eq ["amazing", "description", "info", "iphone", "mobile", "reviews", "summary"]
310
+ end
261
311
  end
262
312
  end
263
313
 
264
314
  context "when using localized fields" do
265
315
  it "should set the keywords from all localizations" do
266
316
  @product = Product.create :brand => "Ford",
267
- :name => "T 1908",
268
- :tags => ["Amazing", "First", "Car"].map { |tag| Tag.new(:name => tag) },
269
- :category => Category.new(:name_translations => { :en => "Vehicle", :de => "Fahrzeug" })
270
- @product._keywords.should include("fahrzeug")
317
+ :name => "T 1908",
318
+ :tags => ["Amazing", "First", "Car"].map { |tag| Tag.new(:name => tag) },
319
+ :category => Category.new(:name_translations => { :en => "Vehicle", :de => "Fahrzeug" })
320
+ expect(@product._keywords).to include("fahrzeug")
321
+ end
322
+ end
323
+
324
+ context "minimum word size" do
325
+ before(:each) do
326
+ Mongoid::Search.minimum_word_size = 3
327
+ end
328
+
329
+ after(:each) do
330
+ Mongoid::Search.minimum_word_size = 2
331
+ end
332
+
333
+ it "should ignore keywords with length less than minimum word size" do
334
+ @product = Product.create :name => 'a'
335
+ expect(@product._keywords.size).to eq 0
336
+
337
+ @product = Product.create :name => 'ap'
338
+ expect(@product._keywords.size).to eq 0
339
+
340
+ @product = Product.create :name => 'app'
341
+ expect(@product._keywords.size).to eq 1
271
342
  end
272
343
  end
273
344
  end
data/spec/util_spec.rb CHANGED
@@ -18,56 +18,56 @@ describe Mongoid::Search::Util do
18
18
  end
19
19
 
20
20
  it "should return an empty array if no text is passed" do
21
- Mongoid::Search::Util.normalize_keywords("").should == []
21
+ expect(Mongoid::Search::Util.normalize_keywords("")).to eq []
22
22
  end
23
23
 
24
24
  it "should return an array of keywords" do
25
- Mongoid::Search::Util.normalize_keywords("keyword").class.should == Array
25
+ expect(Mongoid::Search::Util.normalize_keywords("keyword").class).to eq Array
26
26
  end
27
27
 
28
28
  it "should return an array of strings" do
29
- Mongoid::Search::Util.normalize_keywords("keyword").first.class.should == String
29
+ expect(Mongoid::Search::Util.normalize_keywords("keyword").first.class).to eq String
30
30
  end
31
31
 
32
32
  it "should remove accents from the text passed" do
33
- Mongoid::Search::Util.normalize_keywords("café").should == ["cafe"]
33
+ expect(Mongoid::Search::Util.normalize_keywords("café")).to eq ["cafe"]
34
34
  end
35
35
 
36
36
  it "should downcase the text passed" do
37
- Mongoid::Search::Util.normalize_keywords("CaFé").should == ["cafe"]
37
+ expect(Mongoid::Search::Util.normalize_keywords("CaFé")).to eq ["cafe"]
38
38
  end
39
39
 
40
40
  it "should downcase utf-8 chars of the text passed" do
41
- Mongoid::Search::Util.normalize_keywords("Кафе").should == ["кафе"]
41
+ expect(Mongoid::Search::Util.normalize_keywords("Кафе")).to eq ["кафе"]
42
42
  end
43
43
 
44
44
  it "should split whitespaces, hifens, dots, underlines, etc.." do
45
- Mongoid::Search::Util.normalize_keywords("CaFé-express.com delicious;come visit, and 'win' an \"iPad\"").should == ["cafe", "express", "com", "delicious", "come", "visit", "and", "win", "an", "ipad"]
45
+ expect(Mongoid::Search::Util.normalize_keywords("CaFé-express.com delicious;come visit, and 'win' an \"iPad\"")).to eq ["cafe", "express", "com", "delicious", "come", "visit", "and", "win", "an", "ipad"]
46
46
  end
47
47
 
48
48
  it "should stem keywords" do
49
49
  Mongoid::Search.stem_keywords = true
50
- Mongoid::Search::Util.normalize_keywords("A runner running and eating").should == ["runner", "run", "and", "eat"]
50
+ expect(Mongoid::Search::Util.normalize_keywords("A runner running and eating")).to eq ["runner", "run", "and", "eat"]
51
51
  end
52
52
 
53
53
  it "should stem keywords using a custom proc" do
54
54
  Mongoid::Search.stem_keywords = true
55
55
  Mongoid::Search.stem_proc = lambda { |word| word.upcase }
56
56
 
57
- Mongoid::Search::Util.normalize_keywords("A runner running and eating").should == ["RUNNER", "RUNNING", "AND", "EATING"]
57
+ expect(Mongoid::Search::Util.normalize_keywords("A runner running and eating")).to eq ["RUNNER", "RUNNING", "AND", "EATING"]
58
58
  end
59
59
 
60
60
  it "should ignore keywords from ignore list" do
61
61
  Mongoid::Search.stem_keywords = true
62
62
  Mongoid::Search.ignore_list = YAML.load(File.open(File.dirname(__FILE__) + '/config/ignorelist.yml'))["ignorelist"]
63
- Mongoid::Search::Util.normalize_keywords("An amazing awesome runner running and eating").should == ["an", "runner", "run", "and", "eat"]
63
+ expect(Mongoid::Search::Util.normalize_keywords("An amazing awesome runner running and eating")).to eq ["an", "runner", "run", "and", "eat"]
64
64
  end
65
65
 
66
66
  it "should ignore keywords with less than two words" do
67
- Mongoid::Search::Util.normalize_keywords("A runner running").should_not include "a"
67
+ expect(Mongoid::Search::Util.normalize_keywords("A runner running")).not_to include "a"
68
68
  end
69
69
 
70
70
  it "should not ignore numbers" do
71
- Mongoid::Search::Util.normalize_keywords("Ford T 1908").should include "1908"
71
+ expect(Mongoid::Search::Util.normalize_keywords("Ford T 1908")).to include "1908"
72
72
  end
73
73
  end
metadata CHANGED
@@ -1,94 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_search
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.3.2
4
+ version: 0.3.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Mauricio Zaffari
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-15 00:00:00.000000000 Z
11
+ date: 2017-11-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: mongoid
16
- type: :runtime
17
15
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
16
  requirements:
20
- - - ! '>='
17
+ - - ">="
21
18
  - !ruby/object:Gem::Version
22
19
  version: 3.0.0
20
+ type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 3.0.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: fast-stemmer
32
- type: :runtime
33
29
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
30
  requirements:
36
- - - ~>
31
+ - - "~>"
37
32
  - !ruby/object:Gem::Version
38
33
  version: 1.0.0
34
+ type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 1.0.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: database_cleaner
48
- type: :development
49
43
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
44
  requirements:
52
- - - ! '>='
45
+ - - ">="
53
46
  - !ruby/object:Gem::Version
54
47
  version: 0.8.0
48
+ type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: 0.8.0
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rake
64
- type: :development
65
57
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
58
  requirements:
68
- - - ~>
59
+ - - "<"
69
60
  - !ruby/object:Gem::Version
70
- version: 0.8.7
61
+ version: '11.0'
62
+ type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "<"
76
67
  - !ruby/object:Gem::Version
77
- version: 0.8.7
68
+ version: '11.0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rspec
80
- type: :development
81
71
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
72
  requirements:
84
- - - ~>
73
+ - - "~>"
85
74
  - !ruby/object:Gem::Version
86
75
  version: '2.4'
76
+ type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ~>
80
+ - - "~>"
92
81
  - !ruby/object:Gem::Version
93
82
  version: '2.4'
94
83
  description: Simple full text search implementation.
@@ -98,15 +87,16 @@ executables: []
98
87
  extensions: []
99
88
  extra_rdoc_files: []
100
89
  files:
101
- - lib/mongoid_search/log.rb
102
- - lib/mongoid_search/mongoid_search.rb
103
- - lib/mongoid_search/railtie.rb
104
- - lib/mongoid_search/util.rb
105
- - lib/mongoid_search.rb
106
90
  - LICENSE
107
91
  - README.md
108
92
  - Rakefile
109
93
  - VERSION
94
+ - lib/mongoid_search.rb
95
+ - lib/mongoid_search/log.rb
96
+ - lib/mongoid_search/mongoid_search.rb
97
+ - lib/mongoid_search/railtie.rb
98
+ - lib/mongoid_search/tasks/mongoid_search.rake
99
+ - lib/mongoid_search/util.rb
110
100
  - spec/config/ignorelist.yml
111
101
  - spec/models/category.rb
112
102
  - spec/models/product.rb
@@ -117,36 +107,36 @@ files:
117
107
  - spec/spec_helper.rb
118
108
  - spec/util_spec.rb
119
109
  homepage: http://www.papodenerd.net/mongoid-search-full-text-search-for-your-mongoid-models/
120
- licenses: []
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
121
113
  post_install_message:
122
114
  rdoc_options: []
123
115
  require_paths:
124
116
  - lib
125
117
  required_ruby_version: !ruby/object:Gem::Requirement
126
- none: false
127
118
  requirements:
128
- - - ! '>='
119
+ - - ">="
129
120
  - !ruby/object:Gem::Version
130
121
  version: '0'
131
122
  required_rubygems_version: !ruby/object:Gem::Requirement
132
- none: false
133
123
  requirements:
134
- - - ! '>='
124
+ - - ">="
135
125
  - !ruby/object:Gem::Version
136
126
  version: 1.3.6
137
127
  requirements: []
138
128
  rubyforge_project:
139
- rubygems_version: 1.8.23
129
+ rubygems_version: 2.6.12
140
130
  signing_key:
141
- specification_version: 3
131
+ specification_version: 4
142
132
  summary: Search implementation for Mongoid ORM
143
133
  test_files:
144
- - spec/config/ignorelist.yml
134
+ - spec/models/variant.rb
145
135
  - spec/models/category.rb
146
136
  - spec/models/product.rb
147
- - spec/models/subproduct.rb
148
137
  - spec/models/tag.rb
149
- - spec/models/variant.rb
150
- - spec/mongoid_search_spec.rb
138
+ - spec/models/subproduct.rb
139
+ - spec/config/ignorelist.yml
151
140
  - spec/spec_helper.rb
152
141
  - spec/util_spec.rb
142
+ - spec/mongoid_search_spec.rb