mongoid_search 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f3da97e4dd6f65400548a1e6f12e957fe0c2d5c8a390e015cd8d20572474c73
4
- data.tar.gz: 71423ee292ac1f9e53cb4ef4171d4309c25ca56895203bd53c6bc2d8641fb385
3
+ metadata.gz: 6551ebbcf9e4da8d5ef2bd51036aa3580e7c4023043d228ce88cb8069c8bba31
4
+ data.tar.gz: a1b040501713dbb5d7f874dadeb2a05cc5a0af3f80dc89b4b8b387afa02abb1f
5
5
  SHA512:
6
- metadata.gz: 59b2511bea3017819e52c2633e8ac8cc19158e7da43042584b9fccc4f815b2a2e57fa4b1407e2ee5726d36710473f0cc9143b7b750586c802658869a0c6f7c23
7
- data.tar.gz: 65bfb18a5361a333d815b92bafc34bbe5133c04b28c9e4540397605f98eb76123338119b2b5ee911b5074e85d68d84cc6547ab059845bd4698eb0b5beaaf2f02
6
+ metadata.gz: e24c0139031664d6616db5ba52338850d0cb4b2fbb9e82920a8db4e0cfb87b1cc0dabb9ba4bf17e78699143682f2055bdd5ac9acc9ed9d475decb73d76b06129
7
+ data.tar.gz: f4a234e8c235fa037362715e405e9dc45ea85d18e5de54274b8525e3f5cb9173d6d230696ff7b2031e0f4bcd58bfeaa75a9456a69f00d47088f50bb15f211019
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Mongoid Search
2
2
 
3
- Mongoid Search is a simple full text search implementation for Mongoid ORM. It supports Mongoid 3, 4, 5 and 6 and performs well for small data sets. If your searchable model is big (i.e. 1.000.000+ records), [mongoid_fulltext](https://github.com/mongoid/mongoid_fulltext), ElasticSearch, Solr or Sphinx may suit you better.
3
+ Mongoid Search is a simple full text search implementation for Mongoid ORM. It supports Mongoid 6, 7, and 8 and performs well for small data sets. If your searchable model is big (i.e. 1.000.000+ records), [mongoid_fulltext](https://github.com/mongoid/mongoid_fulltext), ElasticSearch, Solr or Sphinx may suit you better.
4
4
 
5
- [![Build Status](https://travis-ci.org/mongoid/mongoid_search.svg?branch=master)](https://travis-ci.org/mongoid/mongoid_search)
5
+ [![Test](https://github.com/mongoid/mongoid_search/actions/workflows/test.yml/badge.svg)](https://github.com/mongoid/mongoid_search/actions/workflows/test.yml)
6
6
 
7
7
  ## Installation
8
8
 
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
  require 'rake'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Mongoid::Search::Log
2
4
  cattr_accessor :silent
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid::Search
2
4
  extend ActiveSupport::Concern
3
5
 
@@ -11,7 +13,7 @@ module Mongoid::Search
11
13
  @@classes
12
14
  end
13
15
 
14
- module ClassMethods #:nodoc:
16
+ module ClassMethods # :nodoc:
15
17
  # Set a field or a number of fields as sources for search
16
18
  def search_in(*args)
17
19
  args, options = args_and_options(args)
@@ -65,7 +67,7 @@ module Mongoid::Search
65
67
  { options[:index] => kw }
66
68
  end
67
69
 
68
- criteria.send("#{(options[:match])}_of", *keywords_hash)
70
+ criteria.send("#{options[:match]}_of", *keywords_hash)
69
71
  end
70
72
 
71
73
  def args_and_options(args)
@@ -92,7 +94,7 @@ module Mongoid::Search
92
94
  end
93
95
 
94
96
  def search_relevant(query, options)
95
- results_with_relevance(query, options).sort { |o| o['value'] }.map do |r|
97
+ results_with_relevance(query, options).sort_by { |o| o['value'] }.map do |r|
96
98
  new(r['_id'].merge(relevance: r['value'])) do |o|
97
99
  # Need to match the actual object
98
100
  o.instance_variable_set('@new_record', false)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid::Search
2
4
  class Railtie < Rails::Railtie
3
5
  rake_tasks do
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  namespace :mongoid_search do
2
4
  desc 'Goes through all documents with search enabled and indexes the keywords.'
3
5
  task index: :environment do
4
- ::Rails.application.eager_load!
6
+ Rails.application.eager_load!
5
7
  if Mongoid::Search.classes.blank?
6
8
  Mongoid::Search::Log.log "No model to index keywords.\n"
7
9
  else
8
10
  Mongoid::Search.classes.each do |klass|
9
- Mongoid::Search::Log.silent = ENV['SILENT']
11
+ Mongoid::Search::Log.silent = ENV.fetch('SILENT', nil)
10
12
  Mongoid::Search::Log.log "\nIndexing documents for #{klass.name}:\n"
11
13
  klass.index_keywords!
12
14
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Mongoid::Search::Util
3
4
  def self.keywords(klass, fields)
@@ -17,8 +18,8 @@ module Mongoid::Search::Util
17
18
  end
18
19
  end
19
20
  else
20
- value = if klass.respond_to?(fields.to_s + '_translations')
21
- klass.send(fields.to_s + '_translations').values
21
+ value = if klass.respond_to?("#{fields}_translations")
22
+ klass.send("#{fields}_translations").values
22
23
  elsif klass.respond_to?(fields)
23
24
  klass.send(fields)
24
25
  else
@@ -38,15 +39,15 @@ module Mongoid::Search::Util
38
39
  strip_accents = Mongoid::Search.strip_accents
39
40
 
40
41
  return [] if text.blank?
42
+
41
43
  text = text.to_s
42
- .mb_chars
43
44
  .unicode_normalize(:nfkd)
44
45
  .downcase
45
46
  .to_s
46
47
  .gsub(strip_symbols, ' ') # strip symbols
47
48
  .gsub(strip_accents, '') # strip accents
48
- .gsub(/[#{ligatures.keys.join("")}]/) { |c| ligatures[c] }
49
- .split(' ')
49
+ .gsub(/[#{ligatures.keys.join}]/) { |c| ligatures[c] }
50
+ .split
50
51
  .reject { |word| word.size < Mongoid::Search.minimum_word_size }
51
52
  text = text.reject { |word| ignore_list.include?(word) } unless ignore_list.blank?
52
53
  text = text.map(&stem_proc) if stem_keywords
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mongoid_search/mongoid_search'
2
4
 
3
5
  require 'mongoid_search/railtie' if defined?(Rails)
@@ -58,7 +60,7 @@ module Mongoid::Search
58
60
 
59
61
  # Strip special symbols
60
62
  mattr_accessor :strip_symbols
61
- @@strip_symbols = /[._:;'\"`,?|+={}()!@#%^&*<>~\$\-\\\/\[\]]/
63
+ @@strip_symbols = /[._:;'"`,?|+={}()!@#%^&*<>~$\-\\\/\[\]]/
62
64
 
63
65
  # Strip accents
64
66
  mattr_accessor :strip_accents
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauricio Zaffari
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2026-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fast-stemmer
@@ -30,70 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 5.0.0
33
+ version: 6.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 5.0.0
41
- - !ruby/object:Gem::Dependency
42
- name: database_cleaner
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 0.8.0
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 0.8.0
55
- - !ruby/object:Gem::Dependency
56
- name: mongoid-compatibility
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '11.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '11.0'
83
- - !ruby/object:Gem::Dependency
84
- name: rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '2.4'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '2.4'
40
+ version: 6.0.0
97
41
  description: Simple full text search implementation.
98
42
  email:
99
43
  - mauricio@papodenerd.net
@@ -110,20 +54,12 @@ files:
110
54
  - lib/mongoid_search/railtie.rb
111
55
  - lib/mongoid_search/tasks/mongoid_search.rake
112
56
  - lib/mongoid_search/util.rb
113
- - spec/config/ignorelist.yml
114
- - spec/models/category.rb
115
- - spec/models/product.rb
116
- - spec/models/subproduct.rb
117
- - spec/models/tag.rb
118
- - spec/models/variant.rb
119
- - spec/mongoid_search_spec.rb
120
- - spec/spec_helper.rb
121
- - spec/util_spec.rb
122
57
  homepage: https://github.com/mongoid/mongoid_search
123
58
  licenses:
124
59
  - MIT
125
- metadata: {}
126
- post_install_message:
60
+ metadata:
61
+ rubygems_mfa_required: 'true'
62
+ post_install_message:
127
63
  rdoc_options: []
128
64
  require_paths:
129
65
  - lib
@@ -131,24 +67,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
67
  requirements:
132
68
  - - ">="
133
69
  - !ruby/object:Gem::Version
134
- version: '0'
70
+ version: '3.0'
135
71
  required_rubygems_version: !ruby/object:Gem::Requirement
136
72
  requirements:
137
73
  - - ">="
138
74
  - !ruby/object:Gem::Version
139
75
  version: 1.3.6
140
76
  requirements: []
141
- rubygems_version: 3.0.3
142
- signing_key:
77
+ rubygems_version: 3.4.19
78
+ signing_key:
143
79
  specification_version: 4
144
80
  summary: Search implementation for Mongoid ORM
145
- test_files:
146
- - spec/spec_helper.rb
147
- - spec/config/ignorelist.yml
148
- - spec/models/variant.rb
149
- - spec/models/category.rb
150
- - spec/models/tag.rb
151
- - spec/models/product.rb
152
- - spec/models/subproduct.rb
153
- - spec/util_spec.rb
154
- - spec/mongoid_search_spec.rb
81
+ test_files: []
@@ -1,2 +0,0 @@
1
- ignorelist:
2
- amazing, awesome
@@ -1,9 +0,0 @@
1
- class Category
2
- include Mongoid::Document
3
- include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
4
-
5
- field :name, localize: true
6
- field :description
7
-
8
- has_many :products
9
- end
@@ -1,24 +0,0 @@
1
- class Product
2
- include Mongoid::Document
3
- include Mongoid::Search
4
- include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
5
-
6
- field :brand
7
- field :name
8
- field :unit
9
- field :measures, type: Array
10
- field :attrs, type: Array
11
- field :info, type: Hash
12
-
13
- has_many :tags
14
- if Mongoid::Compatibility::Version.mongoid6_or_newer?
15
- belongs_to :category, required: false
16
- else
17
- belongs_to :category
18
- end
19
- embeds_many :subproducts
20
-
21
- search_in :brand, :name, :outlet, :attrs, tags: :name, category: %i[name description],
22
- subproducts: %i[brand name], info: %i[summary description]
23
- search_in :unit, :measures, index: :_unit_keywords
24
- end
@@ -1,9 +0,0 @@
1
- class Subproduct
2
- include Mongoid::Document
3
- include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
4
-
5
- field :brand
6
- field :name
7
-
8
- embedded_in :product, inverse_of: :subproducts
9
- end
data/spec/models/tag.rb DELETED
@@ -1,15 +0,0 @@
1
- class Tag
2
- include Mongoid::Document
3
- include Mongoid::Search
4
- include Mongoid::Attributes::Dynamic if ::Mongoid::VERSION >= '4'
5
-
6
- field :name
7
-
8
- belongs_to :product
9
-
10
- def title
11
- name
12
- end
13
-
14
- search_in :title, product: [:name, { info: %i[summary description], category: %i[name description] }]
15
- end
@@ -1,7 +0,0 @@
1
- autoload :Product, 'models/product.rb'
2
- class Variant < Product
3
- field :color
4
- field :size
5
- search_in :color
6
- search_in :size, index: :_unit_keywords
7
- end
@@ -1,371 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe Mongoid::Search do
4
- before(:all) do
5
- @default_proc = Mongoid::Search.stem_proc
6
- @default_strip_symbols = Mongoid::Search.strip_symbols
7
- @default_strip_accents = Mongoid::Search.strip_accents
8
- end
9
-
10
- after(:all) do
11
- Mongoid::Search.stem_proc = @default_proc
12
- end
13
-
14
- before(:each) do
15
- Mongoid::Search.match = :any
16
- Mongoid::Search.stem_keywords = false
17
- Mongoid::Search.ignore_list = nil
18
- Mongoid::Search.stem_proc = @default_proc
19
- @product = Product.create brand: 'Apple',
20
- name: 'iPhone',
21
- unit: 'mobile olé awesome',
22
- tags: (@tags = %w[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
- end
28
-
29
- describe 'Serialized hash fields' do
30
- context 'when the hash is populated' do
31
- it 'should return the product' do
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
- end
35
- end
36
-
37
- context 'when the hash is empty' do
38
- before(:each) do
39
- @product.info = nil
40
- @product.save
41
- end
42
-
43
- it 'should not return the product' do
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
- end
47
- end
48
- end
49
-
50
- context 'utf-8 characters' do
51
- before do
52
- Mongoid::Search.stem_keywords = false
53
- Mongoid::Search.ignore_list = nil
54
- @product = Product.create brand: 'Эльбрус',
55
- name: 'Процессор',
56
- unit: 'kílográm Olé',
57
- tags: %w[Amazing Awesome Olé].map { |tag| Tag.new(name: tag) },
58
- category: Category.new(name: 'процессоры'),
59
- subproducts: []
60
- end
61
-
62
- it 'should leave utf8 characters' do
63
- expect(@product._keywords).to eq %w[amazing awesome ole процессор процессоры эльбрус]
64
- expect(@product._unit_keywords).to eq %w[kilogram ole]
65
- end
66
-
67
- it "should return results in search when case doesn't match" do
68
- expect(Product.full_text_search('ЭЛЬБРУС').size).to eq 1
69
- expect(Product.full_text_search('KILOGRAM', index: :_unit_keywords).size).to eq 1
70
- end
71
- end
72
-
73
- context 'when references are nil' do
74
- context 'when instance is being created' do
75
- it 'should not complain about method missing' do
76
- expect { Product.create! }.not_to raise_error
77
- end
78
- end
79
-
80
- it 'should validate keywords' do
81
- product = Product.create brand: 'Apple', name: 'iPhone', unit: 'box'
82
- expect(product._keywords).to eq(%w[apple iphone])
83
- expect(product._unit_keywords).to eq(%w[box])
84
- end
85
- end
86
-
87
- it 'should set the _keywords field for array fields also' do
88
- @product.attrs = ['lightweight', 'plastic', :red]
89
- @product.measures = ['box', 'bunch', :bag]
90
- @product.save!
91
- expect(@product._keywords).to include 'lightweight', 'plastic', 'red'
92
- expect(@product._unit_keywords).to include 'box', 'bunch', 'bag'
93
- end
94
-
95
- it 'should inherit _keywords field and build upon' do
96
- variant = Variant.create brand: 'Apple',
97
- name: 'iPhone',
98
- tags: %w[Amazing Awesome Olé].map { |tag| Tag.new(name: tag) },
99
- category: Category.new(name: 'Mobile'),
100
- subproducts: [Subproduct.new(brand: 'Apple', name: 'Craddle')],
101
- color: :white,
102
- size: :big
103
- expect(variant._keywords).to include 'white'
104
- expect(variant._unit_keywords).to include 'big'
105
- expect(Variant.full_text_search(name: 'Apple', color: :white)).to eq [variant]
106
- expect(Variant.full_text_search({ size: 'big' }, index: :_unit_keywords)).to eq [variant]
107
- end
108
-
109
- it 'should expand the ligature to ease searching' do
110
- # ref: http://en.wikipedia.org/wiki/Typographic_ligature, only for french right now. Rules for other languages are not know
111
- variant1 = Variant.create tags: ['œuvre'].map { |tag| Tag.new(name: tag) }
112
- variant2 = Variant.create tags: ['æquo'].map { |tag| Tag.new(name: tag) }
113
- variant3 = Variant.create measures: ['ꜵquo'].map { |measure| measure }
114
-
115
- expect(Variant.full_text_search('œuvre')).to eq [variant1]
116
- expect(Variant.full_text_search('oeuvre')).to eq [variant1]
117
- expect(Variant.full_text_search('æquo')).to eq [variant2]
118
- expect(Variant.full_text_search('aequo')).to eq [variant2]
119
- expect(Variant.full_text_search('aoquo', index: :_unit_keywords)).to eq [variant3]
120
- expect(Variant.full_text_search('ꜵquo', index: :_unit_keywords)).to eq [variant3]
121
- end
122
-
123
- it 'should set the keywords fields with stemmed words if stem is enabled' do
124
- Mongoid::Search.stem_keywords = true
125
- @product.save!
126
- expect(@product._keywords.sort).to eq %w[amaz appl awesom craddl iphon mobil review ol info descript summari].sort
127
- expect(@product._unit_keywords.sort).to eq %w[mobil awesom ol].sort
128
- end
129
-
130
- it 'should set the keywords fields with custom stemmed words if stem is enabled with a custom lambda' do
131
- Mongoid::Search.stem_keywords = true
132
- Mongoid::Search.stem_proc = proc { |word| word.upcase }
133
- @product.save!
134
- expect(@product._keywords.sort).to eq %w[AMAZING APPLE AWESOME CRADDLE DESCRIPTION INFO IPHONE MOBILE OLE REVIEWS SUMMARY]
135
- expect(@product._unit_keywords.sort).to eq %w[AWESOME MOBILE OLE]
136
- end
137
-
138
- it 'should ignore keywords in an ignore list' do
139
- Mongoid::Search.ignore_list = YAML.safe_load(File.open(File.dirname(__FILE__) + '/config/ignorelist.yml'))['ignorelist']
140
- @product.save!
141
- expect(@product._keywords.sort).to eq %w[apple craddle iphone mobile reviews ole info description summary].sort
142
- expect(@product._unit_keywords.sort).to eq %w[mobile ole].sort
143
- end
144
-
145
- it 'should incorporate numbers as keywords' do
146
- @product = Product.create brand: 'Ford',
147
- name: 'T 1908',
148
- tags: %w[Amazing First Car].map { |tag| Tag.new(name: tag) },
149
- category: Category.new(name: 'Vehicle')
150
-
151
- @product.save!
152
- expect(@product._keywords).to eq %w[1908 amazing car first ford vehicle]
153
- end
154
-
155
- it 'should return results in search' do
156
- expect(Product.full_text_search('apple').size).to eq 1
157
- end
158
-
159
- it 'should return results in search for dynamic attribute' do
160
- @product[:outlet] = 'online shop'
161
- @product.save!
162
- expect(Product.full_text_search('online').size).to eq 1
163
- end
164
-
165
- it 'should return results in search even searching a accented word' do
166
- expect(Product.full_text_search('Ole').size).to eq 1
167
- expect(Product.full_text_search('Olé').size).to eq 1
168
- end
169
-
170
- it "should return results in search even if the case doesn't match" do
171
- expect(Product.full_text_search('oLe').size).to eq 1
172
- end
173
-
174
- it 'should return results in search with a partial word by default' do
175
- expect(Product.full_text_search('iph').size).to eq 1
176
- end
177
-
178
- it 'should return results for any matching word with default search' do
179
- expect(Product.full_text_search('apple motorola').size).to eq 1
180
- end
181
-
182
- it 'should not return results when all words do not match, if using :match => :all' do
183
- Mongoid::Search.match = :all
184
- expect(Product.full_text_search('apple motorola').size).to eq 0
185
- end
186
-
187
- it 'should return results for any matching word, using :match => :all, passing :match => :any to .full_text_search' do
188
- Mongoid::Search.match = :all
189
- expect(Product.full_text_search('apple motorola', match: :any).size).to eq 1
190
- end
191
-
192
- it 'should not return results when all words do not match, passing :match => :all to .full_text_search' do
193
- expect(Product.full_text_search('apple motorola', match: :all).size).to eq 0
194
- end
195
-
196
- it 'should return no results when a blank search is made' do
197
- Mongoid::Search.allow_empty_search = false
198
- expect(Product.full_text_search('').size).to eq 0
199
- end
200
-
201
- it 'should return results when a blank search is made when :allow_empty_search is true' do
202
- Mongoid::Search.allow_empty_search = true
203
- expect(Product.full_text_search('').size).to eq 1
204
- end
205
-
206
- it 'should search for embedded documents' do
207
- expect(Product.full_text_search('craddle').size).to eq 1
208
- end
209
-
210
- it 'should search for reference documents' do
211
- expect(Product.full_text_search('reviews').size).to eq 1
212
- end
213
-
214
- it 'should work in a chainable fashion' do
215
- expect(@product.category.products.where(brand: 'Apple').full_text_search('apple').size).to eq 1
216
- expect(@product.category.products.full_text_search('craddle').where(brand: 'Apple').size).to eq 1
217
- end
218
-
219
- it 'should return the classes that include the search module' do
220
- expect(Mongoid::Search.classes.sort_by(&:name)).to eq [Product, Tag]
221
- end
222
-
223
- it 'should have a method to index keywords' do
224
- expect(@product.index_keywords!).to include(true)
225
- end
226
-
227
- it 'should have a class method to index all documents keywords' do
228
- expect(Product.index_keywords!).not_to include(false)
229
- end
230
-
231
- context 'when regex search is false' do
232
- before do
233
- Mongoid::Search.regex_search = false
234
- end
235
-
236
- it 'should not return results in search with a partial word if not using regex search' do
237
- expect(Product.full_text_search('iph').size).to eq 0
238
- end
239
-
240
- it 'should return results in search with a full word if not using regex search' do
241
- expect(Product.full_text_search('iphone').size).to eq 1
242
- end
243
- end
244
-
245
- context 'when regex search is true' do
246
- before do
247
- Mongoid::Search.regex_search = true
248
- end
249
-
250
- after do
251
- Mongoid::Search.regex_search = false
252
- end
253
-
254
- it 'should not return results in search with a partial word if using regex search' do
255
- expect(Product.full_text_search('iph').size).to eq 1
256
- end
257
-
258
- it 'should return results in search with a full word if using regex search' do
259
- expect(Product.full_text_search('iphone').size).to eq 1
260
- end
261
-
262
- context 'when query include special characters that should not be stripped' do
263
- before do
264
- Mongoid::Search.strip_symbols = /[\n]/
265
- Mongoid::Search.strip_accents = /[^\s\p{Graph}]/
266
- end
267
-
268
- after do
269
- Mongoid::Search.strip_symbols = @default_strip_symbols
270
- Mongoid::Search.strip_accents = @default_strip_accents
271
- end
272
-
273
- it 'should escape regex special characters' do
274
- expect(Product.full_text_search('iphone (steve').size).to eq 1
275
- end
276
- end
277
-
278
- context 'Match partial words on the beginning' do
279
- before do
280
- Mongoid::Search.regex = proc { |query| /^#{query}/ }
281
- end
282
-
283
- it 'should return results in search which starts with query string' do
284
- expect(Product.full_text_search('iphone').size).to eq 1
285
- end
286
-
287
- it 'should not return results in search which does not start with query string' do
288
- expect(Product.full_text_search('phone').size).to eq 0
289
- end
290
- end
291
-
292
- context 'Match partial words on the end' do
293
- before do
294
- Mongoid::Search.regex = proc { |query| /#{query}$/ }
295
- end
296
-
297
- it 'should return results in search which ends with query string' do
298
- expect(Product.full_text_search('phone').size).to eq 1
299
- end
300
-
301
- it 'should not return results in search which does not end with query string' do
302
- expect(Product.full_text_search('phon').size).to eq 0
303
- end
304
- end
305
- end
306
-
307
- context 'relevant search' do
308
- before do
309
- Mongoid::Search.relevant_search = true
310
- @imac = Product.create name: 'apple imac'
311
- end
312
-
313
- it 'should return results ordered by relevance and with correct ids' do
314
- expect(Product.full_text_search('apple imac').map(&:_id)).to eq [@imac._id, @product._id]
315
- end
316
-
317
- it 'results should be recognized as persisted objects' do
318
- expect(Product.full_text_search('apple imac').map(&:persisted?)).not_to include false
319
- end
320
-
321
- it 'should include relevance information' do
322
- expect(Product.full_text_search('apple imac').map(&:relevance)).to eq [2, 1]
323
- end
324
- end
325
-
326
- context 'when using methods for keywords' do
327
- it 'should set the _keywords from methods' do
328
- expect(@tags.first._keywords).to include 'amazing'
329
- end
330
- end
331
-
332
- context 'when using deeply nested fields for keywords' do
333
- context 'when explicitly calling set_keywords' do
334
- it 'should set the _keywords from parent' do
335
- @tags.first.send(:set_keywords)
336
- expect(@tags.first._keywords).to eq %w[amazing description info iphone mobile reviews summary]
337
- end
338
- end
339
- end
340
-
341
- context 'when using localized fields' do
342
- it 'should set the keywords from all localizations' do
343
- @product = Product.create brand: 'Ford',
344
- name: 'T 1908',
345
- tags: %w[Amazing First Car].map { |tag| Tag.new(name: tag) },
346
- category: Category.new(name_translations: { en: 'Vehicle', de: 'Fahrzeug' })
347
- expect(@product._keywords).to include('fahrzeug')
348
- end
349
- end
350
-
351
- context 'minimum word size' do
352
- before(:each) do
353
- Mongoid::Search.minimum_word_size = 3
354
- end
355
-
356
- after(:each) do
357
- Mongoid::Search.minimum_word_size = 2
358
- end
359
-
360
- it 'should ignore keywords with length less than minimum word size' do
361
- @product = Product.create name: 'a'
362
- expect(@product._keywords.size).to eq 0
363
-
364
- @product = Product.create name: 'ap'
365
- expect(@product._keywords.size).to eq 0
366
-
367
- @product = Product.create name: 'app'
368
- expect(@product._keywords.size).to eq 1
369
- end
370
- end
371
- end
data/spec/spec_helper.rb DELETED
@@ -1,35 +0,0 @@
1
- require 'simplecov'
2
- SimpleCov.start
3
-
4
- $LOAD_PATH.unshift(File.dirname(__FILE__))
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- require 'mongoid'
7
- require 'database_cleaner'
8
- require 'fast_stemmer'
9
- require 'yaml'
10
- require 'mongoid_search'
11
- require 'mongoid-compatibility'
12
-
13
- Mongoid.configure do |config|
14
- config.connect_to 'mongoid_search_test'
15
- end
16
-
17
- Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |file| require file }
18
-
19
- DatabaseCleaner.orm = :mongoid
20
-
21
- RSpec.configure do |config|
22
- config.before(:all) do
23
- Mongoid.logger.level = Logger::INFO
24
- Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer?
25
- DatabaseCleaner.strategy = :truncation
26
- end
27
-
28
- config.before(:each) do
29
- DatabaseCleaner.start
30
- end
31
-
32
- config.after(:each) do
33
- DatabaseCleaner.clean
34
- end
35
- end
data/spec/util_spec.rb DELETED
@@ -1,72 +0,0 @@
1
-
2
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
-
4
- describe Mongoid::Search::Util do
5
- before(:all) do
6
- @default_proc = Mongoid::Search.stem_proc
7
- end
8
-
9
- after(:all) do
10
- Mongoid::Search.stem_proc = @default_proc
11
- end
12
-
13
- before do
14
- Mongoid::Search.stem_keywords = false
15
- Mongoid::Search.ignore_list = ''
16
- Mongoid::Search.stem_proc = @default_proc
17
- end
18
-
19
- it 'should return an empty array if no text is passed' do
20
- expect(Mongoid::Search::Util.normalize_keywords('')).to eq []
21
- end
22
-
23
- it 'should return an array of keywords' do
24
- expect(Mongoid::Search::Util.normalize_keywords('keyword').class).to eq Array
25
- end
26
-
27
- it 'should return an array of strings' do
28
- expect(Mongoid::Search::Util.normalize_keywords('keyword').first.class).to eq String
29
- end
30
-
31
- it 'should remove accents from the text passed' do
32
- expect(Mongoid::Search::Util.normalize_keywords('café')).to eq ['cafe']
33
- end
34
-
35
- it 'should downcase the text passed' do
36
- expect(Mongoid::Search::Util.normalize_keywords('CaFé')).to eq ['cafe']
37
- end
38
-
39
- it 'should downcase utf-8 chars of the text passed' do
40
- expect(Mongoid::Search::Util.normalize_keywords('Кафе')).to eq ['кафе']
41
- end
42
-
43
- it 'should split whitespaces, hifens, dots, underlines, etc..' do
44
- expect(Mongoid::Search::Util.normalize_keywords("CaFé-express.com delicious;come visit, and 'win' an \"iPad\"")).to eq %w[cafe express com delicious come visit and win an ipad]
45
- end
46
-
47
- it 'should stem keywords' do
48
- Mongoid::Search.stem_keywords = true
49
- expect(Mongoid::Search::Util.normalize_keywords('A runner running and eating')).to eq %w[runner run and eat]
50
- end
51
-
52
- it 'should stem keywords using a custom proc' do
53
- Mongoid::Search.stem_keywords = true
54
- Mongoid::Search.stem_proc = ->(word) { word.upcase }
55
-
56
- expect(Mongoid::Search::Util.normalize_keywords('A runner running and eating')).to eq %w[RUNNER RUNNING AND EATING]
57
- end
58
-
59
- it 'should ignore keywords from ignore list' do
60
- Mongoid::Search.stem_keywords = true
61
- Mongoid::Search.ignore_list = YAML.safe_load(File.open(File.dirname(__FILE__) + '/config/ignorelist.yml'))['ignorelist']
62
- expect(Mongoid::Search::Util.normalize_keywords('An amazing awesome runner running and eating')).to eq %w[an runner run and eat]
63
- end
64
-
65
- it 'should ignore keywords with less than two words' do
66
- expect(Mongoid::Search::Util.normalize_keywords('A runner running')).not_to include 'a'
67
- end
68
-
69
- it 'should not ignore numbers' do
70
- expect(Mongoid::Search::Util.normalize_keywords('Ford T 1908')).to include '1908'
71
- end
72
- end