mongoid_search 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 790663a1de866f407ace368cc503cd724cf4ffc6
4
- data.tar.gz: f95fc5e91b0eb1b12eb95a60bd9c57688ae12bb7
3
+ metadata.gz: 65d13fcd90c890df7b15f2175b701e951259f8de
4
+ data.tar.gz: '097843e60c25fc38ddb96789093dc798a08c5739'
5
5
  SHA512:
6
- metadata.gz: ec1fd1b237c921939f66ca1b7a719f13a1275a19f42e86ef72f368ae7396b21c5fa6ab97e090a070ae656b45bccdaf6607e369a82754e9bfec828f2bca3a1c43
7
- data.tar.gz: 3af9e42610b204de4a78e802bd3efaff38cabfa8a53a1f82b7af191cb9fe31e823e203f3087b606efe2d6fea38b0deb92b3751d2ab49674b410df06b1b40fb31
6
+ metadata.gz: a13b1d7f1bce08ffed931346ec1b1b6750ad984aeb263d93fc1c1db3dd8d03761a763958fb8d000ec19b0ea98b791e3d15020cd152375dbc5d5e19338cc5944f
7
+ data.tar.gz: 71008ecd40e79df705f769d03e0b03953a3278b3cb46ceb325b212e48b8c1321c58aa540750b094d8a94cc9082cbd66e13bba145ebfc7c0af6f78ce7a72fa796
data/README.md CHANGED
@@ -26,12 +26,14 @@ class Product
26
26
  include Mongoid::Search
27
27
  field :brand
28
28
  field :name
29
+ field :unit
29
30
  field :info, type: Hash
30
31
 
31
32
  has_many :tags
32
33
  belongs_to :category
33
34
 
34
35
  search_in :brand, :name, tags: :name, category: :name, info: %i[summary description]
36
+ search_in :unit, index: :_unit_keywords
35
37
  end
36
38
 
37
39
  class Tag
@@ -52,7 +54,7 @@ end
52
54
  Now when you save a product, you get a `_keywords` field automatically:
53
55
 
54
56
  ```ruby
55
- p = Product.new brand: 'Apple', name: 'iPhone', info: { summary: 'Info-summary', description: 'Info-description' }
57
+ p = Product.new brand: 'Apple', name: 'iPhone', unit: 'kilogram', info: { summary: 'Info-summary', description: 'Info-description' }
56
58
  p.tags << Tag.new(name: 'Amazing')
57
59
  p.tags << Tag.new(name: 'Awesome')
58
60
  p.tags << Tag.new(name: 'Superb')
@@ -60,6 +62,8 @@ p.save
60
62
  # => true
61
63
  p._keywords
62
64
  # => ["amazing", "apple", "awesome", "iphone", "superb", "Info-summary", "Info-description"]
65
+ p._unit_keywords
66
+ # => ["kilogram"]
63
67
  ```
64
68
 
65
69
  Now you can run search, which will look in the `_keywords` field and return all matching results:
@@ -69,6 +73,13 @@ Product.full_text_search("apple iphone").size
69
73
  # => 1
70
74
  ```
71
75
 
76
+ Of course, some models could have more than one index. For instance, two different searches with different fields, so you could even specify from which index should be searched:
77
+
78
+ ```ruby
79
+ Product.full_text_search("kilogram", index: :_unit_keywords).size
80
+ # => 1
81
+ ```
82
+
72
83
  Note that the search is case insensitive, and accept partial searching too:
73
84
 
74
85
  ```ruby
@@ -131,6 +142,20 @@ Product.full_text_search('amazing apple', relevant_search: true)
131
142
 
132
143
  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.
133
144
 
145
+ ### index
146
+
147
+ Default is `_keywords`.
148
+
149
+ ```ruby
150
+ Product.full_text_search('amazing apple', index: :_keywords)
151
+ # => [#<Product _id: 5016e7d16af54efe1c000001, _type: nil, brand: "Apple", name: "iPhone", unit: "l", attrs: nil, info: nil, category_id: nil, _keywords: ["amazing", "apple", "awesome", "iphone", "superb"], _unit_keywords: ["l"], relevance: 2.0>]
152
+
153
+ Product.full_text_search('kg', index: :_unit_keywords)
154
+ # => [#<Product _id: 5016e7d16af54efe1c000001, _type: nil, brand: "Apple", name: "iPhone", unit: "kg", attrs: nil, info: nil, category_id: nil, _keywords: ["amazing", "apple", "awesome", "iphone", "superb"], _unit_keywords: ["kg"], relevance: 2.0>]
155
+ ```
156
+
157
+ index enables to have two or more different searches, with different or same fields. It should be noted that indexes are exclusive per each one.
158
+
134
159
  ## Initializer
135
160
 
136
161
  Alternatively, you can create an initializer to setup those options:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.3.6
@@ -50,7 +50,7 @@ module Mongoid::Search
50
50
  # Ligatures to be replaced
51
51
  # http://en.wikipedia.org/wiki/Typographic_ligature
52
52
  mattr_accessor :ligatures
53
- @@ligatures = { 'œ' => 'oe', 'æ' => 'ae' }
53
+ @@ligatures = { 'œ' => 'oe', 'æ' => 'ae', 'ꜵ' => 'ao' }
54
54
 
55
55
  # Minimum word size. Words smaller than it won't be indexed
56
56
  mattr_accessor :minimum_word_size
@@ -14,12 +14,12 @@ module Mongoid::Search
14
14
  module ClassMethods #:nodoc:
15
15
  # Set a field or a number of fields as sources for search
16
16
  def search_in(*args)
17
- args, _options = args_and_options(args)
18
- self.search_fields = (search_fields || []).concat args
17
+ args, options = args_and_options(args)
18
+ set_search_fields(options[:index], args)
19
19
 
20
- field :_keywords, type: Array
20
+ field options[:index], type: Array
21
21
 
22
- index({ _keywords: 1 }, background: true)
22
+ index({ options[:index] => 1 }, background: true)
23
23
 
24
24
  before_save :set_keywords
25
25
  end
@@ -49,13 +49,20 @@ module Mongoid::Search
49
49
 
50
50
  private
51
51
 
52
+ def set_search_fields(index, fields)
53
+ self.search_fields ||= {}
54
+
55
+ (self.search_fields[index] ||= []).concat fields
56
+ end
57
+
52
58
  def query(keywords, options)
53
59
  keywords_hash = keywords.map do |kw|
54
60
  if Mongoid::Search.regex_search
55
61
  escaped_kw = Regexp.escape(kw)
56
62
  kw = Mongoid::Search.regex.call(escaped_kw)
57
63
  end
58
- { _keywords: kw }
64
+
65
+ { options[:index] => kw }
59
66
  end
60
67
 
61
68
  criteria.send("#{(options[:match])}_of", *keywords_hash)
@@ -65,6 +72,7 @@ module Mongoid::Search
65
72
  options = args.last.is_a?(Hash) &&
66
73
  %i[match
67
74
  allow_empty_search
75
+ index
68
76
  relevant_search].include?(args.last.keys.first) ? args.pop : {}
69
77
 
70
78
  [args, extract_options(options)]
@@ -74,7 +82,8 @@ module Mongoid::Search
74
82
  {
75
83
  match: options[:match] || Mongoid::Search.match,
76
84
  allow_empty_search: options[:allow_empty_search] || Mongoid::Search.allow_empty_search,
77
- relevant_search: options[:relevant_search] || Mongoid::Search.relevant_search
85
+ relevant_search: options[:relevant_search] || Mongoid::Search.relevant_search,
86
+ index: options[:index] || :_keywords
78
87
  }
79
88
  end
80
89
 
@@ -99,8 +108,8 @@ module Mongoid::Search
99
108
  function() {
100
109
  var entries = 0;
101
110
  for(i in keywords) {
102
- for(j in this._keywords) {
103
- if(this._keywords[j] == keywords[i]) {
111
+ for(j in this.#{options[:index]}) {
112
+ if(this.#{options[:index]}[j] == keywords[i]) {
104
113
  entries++;
105
114
  }
106
115
  }
@@ -122,11 +131,19 @@ module Mongoid::Search
122
131
  end
123
132
 
124
133
  def index_keywords!
125
- update_attribute(:_keywords, set_keywords)
134
+ search_fields.map do |index, fields|
135
+ update_attribute(index, get_keywords(fields))
136
+ end
126
137
  end
127
138
 
128
139
  def set_keywords
129
- self._keywords = Mongoid::Search::Util.keywords(self, search_fields)
130
- .flatten.reject { |k| k.nil? || k.empty? }.uniq.sort
140
+ search_fields.each do |index, fields|
141
+ send("#{index}=", get_keywords(fields))
142
+ end
143
+ end
144
+
145
+ def get_keywords(fields)
146
+ Mongoid::Search::Util.keywords(self, fields)
147
+ .flatten.reject { |k| k.nil? || k.empty? }.uniq.sort
131
148
  end
132
149
  end
@@ -5,6 +5,8 @@ class Product
5
5
 
6
6
  field :brand
7
7
  field :name
8
+ field :unit
9
+ field :measures, type: Array
8
10
  field :attrs, type: Array
9
11
  field :info, type: Hash
10
12
 
@@ -18,4 +20,5 @@ class Product
18
20
 
19
21
  search_in :brand, :name, :outlet, :attrs, tags: :name, category: %i[name description],
20
22
  subproducts: %i[brand name], info: %i[summary description]
23
+ search_in :unit, :measures, index: :_unit_keywords
21
24
  end
@@ -1,5 +1,7 @@
1
1
  autoload :Product, 'models/product.rb'
2
2
  class Variant < Product
3
3
  field :color
4
+ field :size
4
5
  search_in :color
6
+ search_in :size, index: :_unit_keywords
5
7
  end
@@ -18,6 +18,7 @@ describe Mongoid::Search do
18
18
  Mongoid::Search.stem_proc = @default_proc
19
19
  @product = Product.create brand: 'Apple',
20
20
  name: 'iPhone',
21
+ unit: 'mobile olé awesome',
21
22
  tags: (@tags = %w[Amazing Awesome Olé].map { |tag| Tag.new(name: tag) }),
22
23
  category: Category.new(name: 'Mobile', description: 'Reviews'),
23
24
  subproducts: [Subproduct.new(brand: 'Apple', name: 'Craddle')],
@@ -52,6 +53,7 @@ describe Mongoid::Search do
52
53
  Mongoid::Search.ignore_list = nil
53
54
  @product = Product.create brand: 'Эльбрус',
54
55
  name: 'Процессор',
56
+ unit: 'kílográm Olé',
55
57
  tags: %w[Amazing Awesome Olé].map { |tag| Tag.new(name: tag) },
56
58
  category: Category.new(name: 'процессоры'),
57
59
  subproducts: []
@@ -59,10 +61,12 @@ describe Mongoid::Search do
59
61
 
60
62
  it 'should leave utf8 characters' do
61
63
  expect(@product._keywords).to eq %w[amazing awesome ole процессор процессоры эльбрус]
64
+ expect(@product._unit_keywords).to eq %w[kilogram ole]
62
65
  end
63
66
 
64
67
  it "should return results in search when case doesn't match" do
65
68
  expect(Product.full_text_search('ЭЛЬБРУС').size).to eq 1
69
+ expect(Product.full_text_search('KILOGRAM', index: :_unit_keywords).size).to eq 1
66
70
  end
67
71
  end
68
72
 
@@ -74,15 +78,18 @@ describe Mongoid::Search do
74
78
  end
75
79
 
76
80
  it 'should validate keywords' do
77
- product = Product.create brand: 'Apple', name: 'iPhone'
81
+ product = Product.create brand: 'Apple', name: 'iPhone', unit: 'box'
78
82
  expect(product._keywords).to eq(%w[apple iphone])
83
+ expect(product._unit_keywords).to eq(%w[box])
79
84
  end
80
85
  end
81
86
 
82
87
  it 'should set the _keywords field for array fields also' do
83
88
  @product.attrs = ['lightweight', 'plastic', :red]
89
+ @product.measures = ['box', 'bunch', :bag]
84
90
  @product.save!
85
91
  expect(@product._keywords).to include 'lightweight', 'plastic', 'red'
92
+ expect(@product._unit_keywords).to include 'box', 'bunch', 'bag'
86
93
  end
87
94
 
88
95
  it 'should inherit _keywords field and build upon' do
@@ -91,39 +98,48 @@ describe Mongoid::Search do
91
98
  tags: %w[Amazing Awesome Olé].map { |tag| Tag.new(name: tag) },
92
99
  category: Category.new(name: 'Mobile'),
93
100
  subproducts: [Subproduct.new(brand: 'Apple', name: 'Craddle')],
94
- color: :white
101
+ color: :white,
102
+ size: :big
95
103
  expect(variant._keywords).to include 'white'
104
+ expect(variant._unit_keywords).to include 'big'
96
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]
97
107
  end
98
108
 
99
109
  it 'should expand the ligature to ease searching' do
100
110
  # ref: http://en.wikipedia.org/wiki/Typographic_ligature, only for french right now. Rules for other languages are not know
101
111
  variant1 = Variant.create tags: ['œuvre'].map { |tag| Tag.new(name: tag) }
102
112
  variant2 = Variant.create tags: ['æquo'].map { |tag| Tag.new(name: tag) }
113
+ variant3 = Variant.create measures: ['ꜵquo'].map { |measure| measure }
103
114
 
104
115
  expect(Variant.full_text_search('œuvre')).to eq [variant1]
105
116
  expect(Variant.full_text_search('oeuvre')).to eq [variant1]
106
117
  expect(Variant.full_text_search('æquo')).to eq [variant2]
107
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]
108
121
  end
109
122
 
110
- it 'should set the _keywords field with stemmed words if stem is enabled' do
123
+ it 'should set the keywords fields with stemmed words if stem is enabled' do
111
124
  Mongoid::Search.stem_keywords = true
112
125
  @product.save!
113
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
114
128
  end
115
129
 
116
- it 'should set the _keywords field with custom stemmed words if stem is enabled with a custom lambda' do
130
+ it 'should set the keywords fields with custom stemmed words if stem is enabled with a custom lambda' do
117
131
  Mongoid::Search.stem_keywords = true
118
132
  Mongoid::Search.stem_proc = proc { |word| word.upcase }
119
133
  @product.save!
120
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]
121
136
  end
122
137
 
123
138
  it 'should ignore keywords in an ignore list' do
124
139
  Mongoid::Search.ignore_list = YAML.safe_load(File.open(File.dirname(__FILE__) + '/config/ignorelist.yml'))['ignorelist']
125
140
  @product.save!
126
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
127
143
  end
128
144
 
129
145
  it 'should incorporate numbers as keywords' do
@@ -205,7 +221,7 @@ describe Mongoid::Search do
205
221
  end
206
222
 
207
223
  it 'should have a method to index keywords' do
208
- expect(@product.index_keywords!).to eq true
224
+ expect(@product.index_keywords!).to include(true)
209
225
  end
210
226
 
211
227
  it 'should have a class method to index all documents keywords' do
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.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauricio Zaffari
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-07 00:00:00.000000000 Z
11
+ date: 2018-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fast-stemmer
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  version: 1.3.6
141
141
  requirements: []
142
142
  rubyforge_project:
143
- rubygems_version: 2.6.12
143
+ rubygems_version: 2.6.14
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: Search implementation for Mongoid ORM