mongoid-fts 0.0.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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: