mongoid_fulltext 0.4.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.
data/Gemfile CHANGED
@@ -7,7 +7,6 @@ source "http://rubygems.org"
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
9
  gem "mongoid", "~> 2.0.0"
10
- gem 'database_cleaner', '~> 0.6.0'
11
10
  gem 'rspec', '~> 2.5.0'
12
11
  gem "jeweler", "~> 1.5.2"
13
12
  end
data/README.md CHANGED
@@ -261,6 +261,17 @@ method:
261
261
  The methods on the model level perform bulk removal operations and are therefore faster that
262
262
  updating or removing records individually.
263
263
 
264
+ Mongo Database Indexes
265
+ ----------------------
266
+
267
+ Mongoid provides an indexing mechanism on its models triggered by the `create_indexes` method.
268
+ Mongoid_fulltext will hook into that behavior and create appropriate database indexes on its
269
+ collections. These indexes are required for an efficient full text search.
270
+
271
+ Creating database indexes is typically done with the `db:mongoid:create_indexes` task.
272
+
273
+ rake db:mongoid:create_indexes
274
+
264
275
  Running the specs
265
276
  -----------------
266
277
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -1,3 +1,5 @@
1
+ require 'mongoid_indexes'
2
+
1
3
  module Mongoid::FullTextSearch
2
4
  extend ActiveSupport::Concern
3
5
 
@@ -35,14 +37,18 @@ module Mongoid::FullTextSearch
35
37
  config[:alphabet] = Hash[config[:alphabet].split('').map{ |ch| [ch,ch] }]
36
38
  config[:word_separators] = Hash[config[:word_separators].split('').map{ |ch| [ch,ch] }]
37
39
  self.mongoid_fulltext_config[index_name] = config
38
-
39
- ensure_indexes(index_name, config)
40
40
 
41
41
  before_save :update_ngram_index
42
42
  before_destroy :remove_from_ngram_index
43
43
  end
44
+
45
+ def create_fulltext_indexes
46
+ self.mongoid_fulltext_config.each_pair do |index_name, fulltext_config|
47
+ fulltext_search_ensure_indexes(index_name, fulltext_config)
48
+ end
49
+ end
44
50
 
45
- def ensure_indexes(index_name, config)
51
+ def fulltext_search_ensure_indexes(index_name, config)
46
52
  db = collection.db
47
53
  coll = db.collection(index_name)
48
54
 
@@ -62,7 +68,7 @@ module Mongoid::FullTextSearch
62
68
  next if !keys.member?('ngram')
63
69
  all_filter_keys |= keys.find_all{ |key| key.starts_with?('filter_values.') }
64
70
  if keys & correct_keys != correct_keys
65
- fulltext_log "Droping #{name} [#{keys & correct_keys} <=> #{correct_keys}]"
71
+ Mongoid.logger.info "Droping #{name} [#{keys & correct_keys} <=> #{correct_keys}]"
66
72
  coll.drop_index(name)
67
73
  end
68
74
  end
@@ -71,17 +77,13 @@ module Mongoid::FullTextSearch
71
77
  filter_indexes = all_filter_keys.map { |key| [key, Mongo::ASCENDING] }.sort_by { |filter_index| filter_index[0] }
72
78
  index_definition = [['ngram', Mongo::ASCENDING], ['score', Mongo::DESCENDING]].concat(filter_indexes)
73
79
  end
74
-
75
- fulltext_log "Ensuring fts_index on #{coll.name}: #{index_definition}"
76
- coll.ensure_index(index_definition, { :name => 'fts_index', :background => true })
77
- fulltext_log "Ensuring document_id index on #{coll.name}"
78
- coll.ensure_index([['document_id', Mongo::ASCENDING]], { :background => true }) # to make removes fast
80
+
81
+ Mongoid.logger.info "Ensuring fts_index on #{coll.name}: #{index_definition}"
82
+ coll.ensure_index(index_definition, { :name => 'fts_index' })
83
+ Mongoid.logger.info "Ensuring document_id index on #{coll.name}"
84
+ coll.ensure_index([['document_id', Mongo::ASCENDING]]) # to make removes fast
79
85
  end
80
86
 
81
- def fulltext_log(message)
82
- Mongoid.logger.info("[mongoid_fulltext] #{message}") if Mongoid.logger
83
- end
84
-
85
87
  def fulltext_search(query_string, options={})
86
88
  max_results = options.has_key?(:max_results) ? options.delete(:max_results) : 10
87
89
  return_scores = options.has_key?(:return_scores) ? options.delete(:return_scores) : false
@@ -0,0 +1,12 @@
1
+ # hook onto model index creation to create related FT indexes
2
+ module Mongoid::Indexes::ClassMethods
3
+
4
+ alias_method :create_fulltext_indexes_hook, :create_indexes
5
+
6
+ def create_indexes
7
+ create_fulltext_indexes if respond_to?(:create_fulltext_indexes)
8
+ create_fulltext_indexes_hook
9
+ end
10
+
11
+ end
12
+
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoid_fulltext}
8
- s.version = "0.4.1"
8
+ s.version = "0.4.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Aaron Windsor"]
12
- s.date = %q{2011-07-27}
12
+ s.date = %q{2011-07-28}
13
13
  s.description = %q{Full-text search for the Mongoid ORM, using n-grams extracted from text}
14
14
  s.email = %q{aaron.windsor@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "lib/mongoid_fulltext.rb",
28
+ "lib/mongoid_indexes.rb",
28
29
  "mongoid_fulltext.gemspec",
29
30
  "spec/models/advanced_artwork.rb",
30
31
  "spec/models/basic_artwork.rb",
@@ -70,18 +71,15 @@ Gem::Specification.new do |s|
70
71
 
71
72
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
72
73
  s.add_development_dependency(%q<mongoid>, ["~> 2.0.0"])
73
- s.add_development_dependency(%q<database_cleaner>, ["~> 0.6.0"])
74
74
  s.add_development_dependency(%q<rspec>, ["~> 2.5.0"])
75
75
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
76
76
  else
77
77
  s.add_dependency(%q<mongoid>, ["~> 2.0.0"])
78
- s.add_dependency(%q<database_cleaner>, ["~> 0.6.0"])
79
78
  s.add_dependency(%q<rspec>, ["~> 2.5.0"])
80
79
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
81
80
  end
82
81
  else
83
82
  s.add_dependency(%q<mongoid>, ["~> 2.0.0"])
84
- s.add_dependency(%q<database_cleaner>, ["~> 0.6.0"])
85
83
  s.add_dependency(%q<rspec>, ["~> 2.5.0"])
86
84
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
87
85
  end
@@ -16,6 +16,7 @@ module Mongoid
16
16
  end
17
17
 
18
18
  end
19
+
19
20
  context "with default settings" do
20
21
 
21
22
  let!(:flower_myth) { BasicArtwork.create(:title => 'Flower Myth') }
@@ -125,6 +126,7 @@ module Mongoid
125
126
  end
126
127
 
127
128
  end
129
+
128
130
  context "with an index name specified" do
129
131
  let!(:pablo_picasso) { ExternalArtist.create(:full_name => 'Pablo Picasso') }
130
132
  let!(:portrait_of_picasso) { ExternalArtwork.create(:title => 'Portrait of Picasso') }
@@ -188,6 +190,7 @@ module Mongoid
188
190
  end
189
191
 
190
192
  end
193
+
191
194
  context "with an index name specified" do
192
195
 
193
196
  let!(:andy_warhol) { ExternalArtist.create(:full_name => 'Andy Warhol') }
@@ -202,6 +205,7 @@ module Mongoid
202
205
  end
203
206
 
204
207
  end
208
+
205
209
  context "with an index name specified" do
206
210
 
207
211
  let!(:pop) { ExternalArtwork.create(:title => 'Pop') }
@@ -237,6 +241,7 @@ module Mongoid
237
241
  end
238
242
 
239
243
  end
244
+
240
245
  context "with an index name specified" do
241
246
 
242
247
  it "cleans up item from the index after they're destroyed" do
@@ -250,6 +255,7 @@ module Mongoid
250
255
  end
251
256
 
252
257
  end
258
+
253
259
  context "with an index name specified and no fields provided to index" do
254
260
 
255
261
  let!(:big_bang) { ExternalArtworkNoFieldsSupplied.create(:title => 'Big Bang', :artist => 'David Poppie', :year => '2009') }
@@ -261,6 +267,7 @@ module Mongoid
261
267
  end
262
268
 
263
269
  end
270
+
264
271
  context "with multiple indexes defined" do
265
272
 
266
273
  let!(:pop) { MultiExternalArtwork.create(:title => 'Pop', :year => '1970', :artist => 'Joe Schmoe') }
@@ -282,6 +289,7 @@ module Mongoid
282
289
  end
283
290
 
284
291
  end
292
+
285
293
  context "with multiple fields indexed and the same index used by multiple models" do
286
294
 
287
295
  let!(:andy_warhol) { MultiFieldArtist.create(:full_name => 'Andy Warhol', :birth_year => '1928') }
@@ -338,6 +346,9 @@ module Mongoid
338
346
  # fields as well as the union of all the filter fields to allow for efficient lookups.
339
347
 
340
348
  it "creates a proper index for searching efficiently" do
349
+ [ FilteredArtwork, FilteredArtist, FilteredOther].each do |klass|
350
+ klass.create_indexes
351
+ end
341
352
  index_collection = FilteredArtwork.collection.db.collection('mongoid_fulltext.artworks_and_artists')
342
353
  ngram_indexes = index_collection.index_information.find_all{ |name, definition| definition['key'].has_key?('ngram') }
343
354
  ngram_indexes.length.should == 1
@@ -431,7 +442,37 @@ module Mongoid
431
442
 
432
443
  end
433
444
 
445
+ context "mongoid indexes" do
446
+ it "can re-create dropped indexes" do
447
+ # there're no indexes by default as Mongoid.autocreate_indexes is set to false
448
+ # but mongo will automatically attempt to index _id in the background
449
+ Mongoid.master["mongoid_fulltext.index_basicartwork_0"].index_information.size.should <= 1
450
+ BasicArtwork.create_indexes
451
+ Mongoid.master["mongoid_fulltext.index_basicartwork_0"].index_information.should ==
452
+ {
453
+ "_id_" => {
454
+ "name" => "_id_",
455
+ "ns" => "mongoid_fulltext_test.mongoid_fulltext.index_basicartwork_0",
456
+ "key" => { "_id" => 1 },
457
+ "v" => 0
458
+ },
459
+ "fts_index" => {
460
+ "name" => "fts_index",
461
+ "ns" => "mongoid_fulltext_test.mongoid_fulltext.index_basicartwork_0",
462
+ "key" => { "ngram" => 1, "score" => -1 },
463
+ "v" => 0
464
+ },
465
+ "document_id_1" => {
466
+ "name" => "document_id_1",
467
+ "ns" => "mongoid_fulltext_test.mongoid_fulltext.index_basicartwork_0",
468
+ "key" => { "document_id" => 1 },
469
+ "v"=>0
470
+ }
471
+ }
472
+ end
473
+
474
+ end
475
+
434
476
  end
435
-
436
477
  end
437
478
  end
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,6 @@ require 'bundler/setup'
3
3
  require 'rspec'
4
4
 
5
5
  require 'mongoid'
6
- require 'database_cleaner'
7
6
 
8
7
  Mongoid.configure do |config|
9
8
  name = "mongoid_fulltext_test"
@@ -15,8 +14,11 @@ require File.expand_path("../../lib/mongoid_fulltext", __FILE__)
15
14
  Dir["#{File.dirname(__FILE__)}/models/**/*.rb"].each { |f| require f }
16
15
 
17
16
  Rspec.configure do |c|
18
- c.before(:all) { DatabaseCleaner.strategy = :truncation }
19
- c.before(:each) { DatabaseCleaner.clean }
20
- c.after(:all) { Mongoid.master.command({'repairDatabase' => 1}) }
17
+ c.before(:each) do
18
+ Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
19
+ end
20
+ c.after(:all) do
21
+ Mongoid.master.command({'dropDatabase' => 1})
22
+ end
21
23
  end
22
24
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_fulltext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-27 00:00:00.000000000 -04:00
12
+ date: 2011-07-28 00:00:00.000000000 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: mongoid
17
- requirement: &75050220 !ruby/object:Gem::Requirement
17
+ requirement: &86604030 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,21 +22,10 @@ dependencies:
22
22
  version: 2.0.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *75050220
26
- - !ruby/object:Gem::Dependency
27
- name: database_cleaner
28
- requirement: &75049790 !ruby/object:Gem::Requirement
29
- none: false
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: 0.6.0
34
- type: :development
35
- prerelease: false
36
- version_requirements: *75049790
25
+ version_requirements: *86604030
37
26
  - !ruby/object:Gem::Dependency
38
27
  name: rspec
39
- requirement: &75049460 !ruby/object:Gem::Requirement
28
+ requirement: &86603130 !ruby/object:Gem::Requirement
40
29
  none: false
41
30
  requirements:
42
31
  - - ~>
@@ -44,10 +33,10 @@ dependencies:
44
33
  version: 2.5.0
45
34
  type: :development
46
35
  prerelease: false
47
- version_requirements: *75049460
36
+ version_requirements: *86603130
48
37
  - !ruby/object:Gem::Dependency
49
38
  name: jeweler
50
- requirement: &75049090 !ruby/object:Gem::Requirement
39
+ requirement: &86602120 !ruby/object:Gem::Requirement
51
40
  none: false
52
41
  requirements:
53
42
  - - ~>
@@ -55,7 +44,7 @@ dependencies:
55
44
  version: 1.5.2
56
45
  type: :development
57
46
  prerelease: false
58
- version_requirements: *75049090
47
+ version_requirements: *86602120
59
48
  description: Full-text search for the Mongoid ORM, using n-grams extracted from text
60
49
  email: aaron.windsor@gmail.com
61
50
  executables: []
@@ -72,6 +61,7 @@ files:
72
61
  - Rakefile
73
62
  - VERSION
74
63
  - lib/mongoid_fulltext.rb
64
+ - lib/mongoid_indexes.rb
75
65
  - mongoid_fulltext.gemspec
76
66
  - spec/models/advanced_artwork.rb
77
67
  - spec/models/basic_artwork.rb
@@ -104,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
94
  version: '0'
105
95
  segments:
106
96
  - 0
107
- hash: 871827713
97
+ hash: 229668173
108
98
  required_rubygems_version: !ruby/object:Gem::Requirement
109
99
  none: false
110
100
  requirements: