mongoid_fulltext 0.4.1 → 0.4.2

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