mongoid-fts 0.0.1 → 0.4.2

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.
Files changed (4) hide show
  1. data/README.md +73 -18
  2. data/lib/mongoid-fts.rb +33 -23
  3. data/mongoid-fts.gemspec +43 -0
  4. metadata +2 -1
data/README.md CHANGED
@@ -1,53 +1,108 @@
1
1
  NAME
2
+
2
3
  mongoid-fts.rb
3
4
 
4
5
  DESCRIPTION
6
+
5
7
  enable mongodb's new fulltext simply and quickly on your mongoid models, including pagination.
6
8
 
9
+
10
+ INSTALL
11
+
12
+ ````ruby
13
+
14
+ gem 'mongoid-fts'
15
+
16
+ ````
17
+
18
+ ````bash
19
+
20
+ # required
21
+
22
+ ~> bundle install
23
+
24
+ ~> rake db:mongoid:created_indexes
25
+
26
+ # optional (this is done automatically)
27
+
28
+ ~> rails runner 'Mongoid::FTS.enable!'
29
+
30
+ ````
31
+
7
32
  SYNOPSIS
8
33
 
9
34
  ````ruby
10
35
 
36
+ # use the mixin method on your models to give them a 'search' method. fts
37
+ # will attempt to guess which fields you mean to search. title will be
38
+ # weighted most highly, then the array of keywords, then the fulltext of the
39
+ # model
40
+ #
11
41
  class A
12
42
  include Mongoid::Document
13
43
  include Mongoid::FTS
14
44
 
15
45
  field(:title)
16
- field(:body)
17
-
18
- def to_search
19
- {:title => title, :fulltext => body}
20
- end
46
+ field(:keywords, :type => Array)
47
+ field(:fulltext)
21
48
  end
22
49
 
50
+ # if your fields are named like this you can certain override what's indexed
51
+ #
23
52
 
24
53
  class B
25
54
  include Mongoid::Document
26
55
  include Mongoid::FTS
27
56
 
28
- field(:title)
29
- field(:body)
57
+ field(:a)
58
+ field(:b, :type => Array, :default => [])
59
+ field(:c)
30
60
 
31
61
  def to_search
32
- {:title => title, :fulltext => body}
62
+ {:title => a, :keywords => (b + ['foobar']), :fulltext => c}
33
63
  end
34
64
  end
35
65
 
36
66
 
67
+ # after this searching is pretty POLS
68
+ #
69
+
37
70
  A.create!(:title => 'foo', :body => 'cats')
38
- A.create!(:title => 'bar', :body => 'dogs')
71
+ A.create!(:title => 'foo', :body => 'cat')
72
+
73
+ p A.search('cat').size #=> 2
74
+
75
+ # you can to cross-model searches like so
76
+ #
77
+ p Mongoid::FTS.search('cat', :models => [A, B])
78
+ p Mongoid::FTS.search('dog', :models => [A, B])
79
+
80
+ # pagination is supported with an ugly hack
81
+
82
+ A.search('cats').page(10).per(3)
39
83
 
40
- B.create!(:title => 'foo', :body => 'cats')
41
- B.create!(:title => 'bar', :body => 'dogs')
84
+ # or
42
85
 
43
- p FTS.search('cat', :models => [A, B])
44
- p FTS.search('dog', :models => [A, B])
86
+ A.search('cats').paginate(:page => 10, :per => 3)
45
87
 
46
- p A.search('cat')
47
- p B.search('cat')
48
- p A.search('dog')
49
- p B.search('dog')
50
88
 
51
- p A.search('cat dog').page(1).per(1)
89
+ # handy to know
90
+
91
+ Mongoid::FTS::Index.rebuild! # re-index every currently known object - not super effecient
92
+
93
+ Mongoid::FTS::Index.reset! # completely drop/create indexes - lose all objects
52
94
 
53
95
  ````
96
+
97
+ the implementation is has only a work around for pagination, see
98
+
99
+ https://groups.google.com/forum/#!topic/mongodb-user/2hUgOAN4KKk
100
+
101
+ for details
102
+
103
+
104
+ regardless, the *interface* of this mixin is uber simple and should be quite
105
+ future proof. as the mongodb teams moves search forward i'll track the new
106
+ implementation and preserve the current interface. until it settles down,
107
+ however, i'll resist adding new features.
108
+
@@ -1,7 +1,7 @@
1
1
  module Mongoid
2
2
  module FTS
3
3
  #
4
- const_set(:Version, '0.0.1') unless const_defined?(:Version)
4
+ const_set(:Version, '0.4.2') unless const_defined?(:Version)
5
5
 
6
6
  class << FTS
7
7
  def version
@@ -58,9 +58,7 @@ module Mongoid
58
58
 
59
59
  #
60
60
  def FTS.search(*args)
61
- options = args.extract_options!.to_options!
62
-
63
- args.push(options)
61
+ options = Map.options_for(args)
64
62
 
65
63
  _searches = FTS._search(*args)
66
64
 
@@ -68,7 +66,7 @@ module Mongoid
68
66
  end
69
67
 
70
68
  def FTS._search(*args)
71
- options = args.extract_options!.to_options!
69
+ options = Map.options_for!(args)
72
70
 
73
71
  search = args.join(' ')
74
72
 
@@ -76,7 +74,7 @@ module Mongoid
76
74
  limit = [Integer(options.delete(:limit) || 128), 1].max
77
75
  models = [options.delete(:models), options.delete(:model)].flatten.compact
78
76
 
79
- models = FTS.models if models.blank?
77
+ models = FTS.models if models.empty?
80
78
 
81
79
  _searches =
82
80
  models.map do |model|
@@ -135,7 +133,7 @@ module Mongoid
135
133
  end
136
134
 
137
135
  def paginate(*args)
138
- options = args.extract_options!.to_options!
136
+ options = Map.options_for!(args)
139
137
 
140
138
  page = Integer(args.shift || options[:page] || @page)
141
139
  per = Integer(args.shift || options[:per] || options[:size] || @per)
@@ -157,7 +155,7 @@ module Mongoid
157
155
  if args.empty?
158
156
  return @page
159
157
  else
160
- options = args.extract_options!.to_options!
158
+ options = Map.options_for!(args)
161
159
  page = args.shift || options[:page]
162
160
  options[:page] = page
163
161
  paginate(options)
@@ -168,7 +166,7 @@ module Mongoid
168
166
  if args.empty?
169
167
  return @per
170
168
  else
171
- options = args.extract_options!.to_options!
169
+ options = Map.options_for!(args)
172
170
  per = args.shift || options[:per]
173
171
  options[:per] = per
174
172
  paginate(options)
@@ -290,19 +288,19 @@ module Mongoid
290
288
  def normalize!
291
289
  index = self
292
290
 
293
- unless index.keywords.blank?
291
+ unless [index.keywords].join.strip.empty?
294
292
  index.keywords = FTS.list_of_strings(index.keywords)
295
293
  end
296
294
 
297
- unless index.title.blank?
295
+ unless [index.title].join.strip.empty?
298
296
  index.title = index.title.to_s.strip
299
297
  end
300
298
 
301
- unless index.keywords.blank?
299
+ unless [index.keywords].join.strip.empty?
302
300
  index.keywords = index.keywords.map{|keyword| keyword.strip}
303
301
  end
304
302
 
305
- unless index.fulltext.blank?
303
+ unless [index.fulltext].join.strip.empty?
306
304
  index.fulltext = index.fulltext.to_s.strip
307
305
  end
308
306
 
@@ -428,7 +426,7 @@ module Mongoid
428
426
  @code ||= proc do
429
427
  class << self
430
428
  def search(*args, &block)
431
- args.push(options = args.extract_options!.to_options!)
429
+ options = Map.options_for(args)
432
430
 
433
431
  options[:model] = self
434
432
 
@@ -436,7 +434,7 @@ module Mongoid
436
434
  end
437
435
 
438
436
  def _search(*args, &block)
439
- args.push(options = args.extract_options!.to_options!)
437
+ options = Map.options_for(args)
440
438
 
441
439
  options[:model] = self
442
440
 
@@ -517,15 +515,21 @@ module Mongoid
517
515
  models
518
516
  end
519
517
 
520
- def FTS.enable!
521
- session = Mongoid::Sessions.default
522
- session.with(database: :admin).command({ setParameter: 1, textFTSEnabled: true })
523
- end
518
+ def FTS.enable!(*args)
519
+ options = Map.options_for!(args)
524
520
 
525
- begin
526
- FTS.enable!
527
- rescue Object => e
528
- warn "failed to enable search with #{ e.class }(#{ e.message })"
521
+ unless options.has_key?(:warn)
522
+ options[:warn] = true
523
+ end
524
+
525
+ begin
526
+ session = Mongoid::Sessions.default
527
+ session.with(database: :admin).command({ setParameter: 1, textSearchEnabled: true })
528
+ rescue Object => e
529
+ unless e.is_a?(Mongoid::Errors::NoSessionsConfig)
530
+ warn "failed to enable search with #{ e.class }(#{ e.message })"
531
+ end
532
+ end
529
533
  end
530
534
  end
531
535
 
@@ -534,7 +538,13 @@ module Mongoid
534
538
  if defined?(Rails)
535
539
  class FTS::Engine < ::Rails::Engine
536
540
  paths['app/models'] = ::File.dirname(__FILE__)
541
+
542
+ config.after_initialize do
543
+ Mongoid::FTS.enable!(:warn => true)
544
+ end
537
545
  end
546
+ else
547
+ Mongoid::FTS.enable!(:warn => true)
538
548
  end
539
549
  end
540
550
 
@@ -0,0 +1,43 @@
1
+ ## mongoid-fts.gemspec
2
+ #
3
+
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "mongoid-fts"
6
+ spec.version = "0.4.2"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "mongoid-fts"
9
+ spec.description = "enable mongodb's new fulltext simply and quickly on your mongoid models, including pagination."
10
+
11
+ spec.files =
12
+ ["README.md",
13
+ "Rakefile",
14
+ "lib",
15
+ "lib/app",
16
+ "lib/app/mongoid",
17
+ "lib/app/mongoid/fts",
18
+ "lib/app/mongoid/fts/index.rb",
19
+ "lib/mongoid",
20
+ "lib/mongoid-fts.rb",
21
+ "mongoid-fts.gemspec"]
22
+
23
+ spec.executables = []
24
+
25
+ spec.require_path = "lib"
26
+
27
+ spec.test_files = nil
28
+
29
+
30
+ spec.add_dependency(*["mongoid", "~> 3.1"])
31
+
32
+ spec.add_dependency(*["map", "~> 6.5"])
33
+
34
+ spec.add_dependency(*["coerce", "~> 0.0"])
35
+
36
+
37
+ spec.extensions.push(*[])
38
+
39
+ spec.rubyforge_project = "codeforpeople"
40
+ spec.author = "Ara T. Howard"
41
+ spec.email = "ara.t.howard@gmail.com"
42
+ spec.homepage = "https://github.com/ahoward/mongoid-fts"
43
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-fts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -70,6 +70,7 @@ files:
70
70
  - Rakefile
71
71
  - lib/app/mongoid/fts/index.rb
72
72
  - lib/mongoid-fts.rb
73
+ - mongoid-fts.gemspec
73
74
  homepage: https://github.com/ahoward/mongoid-fts
74
75
  licenses: []
75
76
  post_install_message: