mongoid-sphinx 0.1.3 → 0.1.4

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.
@@ -6,7 +6,7 @@ require 'mongoid_sphinx/context'
6
6
  require 'mongoid_sphinx/index'
7
7
  require 'mongoid_sphinx/mongoid/identity'
8
8
  require 'mongoid_sphinx/mongoid/sphinx'
9
- require 'mongoid_sphinx/railtie'
9
+ require 'mongoid_sphinx/railtie' if defined?(Rails)
10
10
 
11
11
  module MongoidSphinx
12
12
 
@@ -52,4 +52,4 @@ module MongoidSphinx
52
52
  end
53
53
  end
54
54
 
55
- end
55
+ end
@@ -19,22 +19,25 @@ module MongoidSphinx
19
19
  ondisk_dict overshort_step phrase_boundary phrase_boundary_step preopen
20
20
  stopwords stopwords_step wordforms )
21
21
 
22
+ attr_accessor :allow_star
22
23
  attr_accessor :searchd_file_path, :model_directories, :indexed_models
23
24
  attr_accessor :source_options, :index_options
24
25
  attr_accessor :configuration, :controller
25
26
 
26
27
  def initialize
28
+ init_root_env
27
29
  @configuration = Riddle::Configuration.new
28
- @configuration.searchd.pid_file = "#{Rails.root}/log/searchd.#{Rails.env}.pid"
29
- @configuration.searchd.log = "#{Rails.root}/log/searchd.log"
30
- @configuration.searchd.query_log = "#{Rails.root}/log/searchd.query.log"
30
+ @configuration.searchd.pid_file = "#{@root}/log/searchd.#{@env}.pid"
31
+ @configuration.searchd.log = "#{@root}/log/searchd.log"
32
+ @configuration.searchd.query_log = "#{@root}/log/searchd.query.log"
31
33
 
32
- @controller = Riddle::Controller.new @configuration, "#{Rails.root}/config/#{Rails.env}.sphinx.conf"
34
+ @controller = Riddle::Controller.new @configuration, "#{@root}/config/#{@env}.sphinx.conf"
33
35
 
34
36
  self.address = "127.0.0.1"
35
37
  self.port = 9312
36
- self.searchd_file_path = "#{Rails.root}/db/sphinx/#{Rails.env}"
37
- self.model_directories = ["#{Rails.root}/app/models/"] + Dir.glob("#{Rails.root}/vendor/plugins/*/app/models/")
38
+ self.searchd_file_path = "#{@root}/db/sphinx/#{@env}"
39
+ self.allow_star = false
40
+ self.model_directories = ["#{@root}/app/models/"] + Dir.glob("#{@root}/vendor/plugins/*/app/models/")
38
41
  self.indexed_models = []
39
42
 
40
43
  self.source_options = {
@@ -156,15 +159,45 @@ module MongoidSphinx
156
159
  private
157
160
 
158
161
  def parse_config
159
- path = "#{Rails.root}/config/sphinx.yml"
162
+ path = "#{@root}/config/sphinx.yml"
160
163
  return unless File.exists?(path)
161
164
 
162
- conf = YAML::load(ERB.new(IO.read(path)).result)[Rails.env]
165
+ conf = YAML::load(ERB.new(IO.read(path)).result)[@env]
163
166
 
164
- conf.each do |key,value|
165
- self.send("#{key}=", value) if self.respond_to?("#{key}=")
167
+ unless conf.nil?
168
+ conf.each do |key,value|
169
+ self.send("#{key}=", value) if self.respond_to?("#{key}=")
170
+
171
+ set_sphinx_setting self.source_options, key, value, SourceOptions
172
+ set_sphinx_setting self.index_options, key, value, IndexOptions
173
+ set_sphinx_setting @configuration.searchd, key, value
174
+ set_sphinx_setting @configuration.indexer, key, value
175
+ end
176
+ end
177
+
178
+ if self.allow_star
179
+ self.index_options[:enable_star] = true
180
+ self.index_options[:min_prefix_len] = 1
166
181
  end
167
182
  end
168
183
 
184
+ def init_root_env
185
+ if defined?(Rails)
186
+ @root = Rails.root
187
+ @env = Rails.env
188
+ else
189
+ @root = Dir.pwd
190
+ @env = ENV['RACK_ENV'] || 'development'
191
+ end
192
+ end
193
+
194
+ def set_sphinx_setting(object, key, value, allowed = {})
195
+ if object.is_a?(Hash)
196
+ object[key.to_sym] = value if allowed.include?(key.to_s)
197
+ else
198
+ object.send("#{key}=", value) if object.respond_to?("#{key}")
199
+ send("#{key}=", value) if self.respond_to?("#{key}")
200
+ end
201
+ end
169
202
  end
170
- end
203
+ end
@@ -0,0 +1,74 @@
1
+ module MongoidSphinx
2
+ module Delta
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ after_save :update_index
6
+ after_save :index_delta
7
+ end
8
+
9
+ def index_delta
10
+ config = MongoidSphinx::Configuration.instance
11
+ rotate = MongoidSphinx.sphinx_running? ? "--rotate" : ""
12
+
13
+ output = `#{config.bin_path}#{config.indexer_binary_name} --config "#{config.config_file}" #{rotate} #{model.sphinx_index.delta_name.join(' ')}`
14
+ end
15
+
16
+ def update_indeces
17
+ attrs = self.changes.select do |key, value|
18
+ self.search_fields.include?(key) || self.search_attributes.include?(key)
19
+ end
20
+
21
+ attribute_names = attrs.keys.collect{|key| key.to_s}
22
+
23
+ # Prepare attributes for indexing
24
+ self.search_attributes.each do |key, value|
25
+ case value.class
26
+ when Hash
27
+ entries = []
28
+ self.document_hash[key.to_s].to_a.each do |entry|
29
+ entries << entry.join(" : ")
30
+ end
31
+ attrs[key] = entries.join(", ")
32
+ when Array
33
+ attrs[key] = self.document_hash[key.to_s].join(", ")
34
+ when Date
35
+ attrs[key] = self.document_hash[key.to_s].to_time.to_i
36
+ when DateTime || Time
37
+ attrs[key] = self.document_hash[key.to_s].to_i
38
+ when Boolean
39
+ attrs[key] = self.document_hash[key.to_s] ? 1 : 0
40
+ else
41
+ attrs[key] = self.document_hash[key.to_s].to_s
42
+ end
43
+ end
44
+
45
+ # Prepare fields for indexing
46
+ self.search_fields.each do |key|
47
+ if document_hash[key.to_s].is_a?(Array)
48
+ attrs[key] = "<#{key}><![CDATA[[#{document_hash[key.to_s].join(", ")}]]></#{key}>"
49
+ elsif document_hash[key.to_s].is_a?(Hash)
50
+ entries = []
51
+ document_hash[key.to_s].to_a.each do |entry|
52
+ entries << entry.join(" : ")
53
+ end
54
+ attrs[key] = "<#{key}><![CDATA[[#{entries.join(", ")}]]></#{key}>"
55
+ else
56
+ attrs[key] = "<#{key}><![CDATA[[#{document_hash[key.to_s]}]]></#{key}>"
57
+ end
58
+ end
59
+
60
+ attribute_values = attrs.values
61
+ # Update core first (update existing records)
62
+ update_index self.class.sphinx_index.core_name, attribute_names, attribute_values
63
+ # Update delta (new records)
64
+ update_index self.class.sphinx_index.delta_name, attribute_names, attribute_values
65
+ end
66
+
67
+ def update_index(index_name, attribute_names, attribute_values)
68
+ client = MongoidSphinx::Configuration.instance.client
69
+ if self.class.seach_ids(self.sphinx_id..self.sphinx_id, :index => index_name,:raw => true)
70
+ client.update index_name, attribute_names, {self.sphinx_id => attribute_values}
71
+ end
72
+ end
73
+ end
74
+ end
@@ -7,13 +7,21 @@ module MongoidSphinx
7
7
  @model = model
8
8
  @options = model.index_options
9
9
  @source = Riddle::Configuration::XMLSource.new( "#{core_name}_0", config.source_options[:type])
10
- @source.xmlpipe_command = "RAILS_ENV=#{Rails.env} script/rails runner '#{model.to_s}.sphinx_stream'"
10
+ if defined?(Rails)
11
+ @source.xmlpipe_command = "RAILS_ENV=#{Rails.env} script/rails runner '#{model.to_s}.sphinx_stream'"
12
+ else
13
+ @source.xmlpipe_command = "script/runner '#{model.to_s}.sphinx_stream'"
14
+ end
11
15
  end
12
16
 
13
17
  def core_name
14
18
  "#{name}_core"
15
19
  end
16
20
 
21
+ def delta_name
22
+ "#{name}_delta"
23
+ end
24
+
17
25
  def self.name_for(model)
18
26
  model.name.underscore.tr(':/\\', '_')
19
27
  end
@@ -5,19 +5,22 @@ module Mongoid
5
5
  module Sphinx
6
6
  extend ActiveSupport::Concern
7
7
  included do
8
- SPHINX_TYPE_MAPPING = {
9
- 'Date' => 'timestamp',
10
- 'DateTime' => 'timestamp',
11
- 'Time' => 'timestamp',
12
- 'Float' => 'float',
13
- 'Integer' => 'int',
14
- 'BigDecimal' => 'float',
15
- 'Boolean' => 'bool'
16
- }
8
+ unless defined?(SPHINX_TYPE_MAPPING)
9
+ SPHINX_TYPE_MAPPING = {
10
+ 'Date' => 'timestamp',
11
+ 'DateTime' => 'timestamp',
12
+ 'Time' => 'timestamp',
13
+ 'Float' => 'float',
14
+ 'Integer' => 'int',
15
+ 'BigDecimal' => 'float',
16
+ 'Boolean' => 'bool'
17
+ }
18
+ end
17
19
 
18
20
  cattr_accessor :search_fields
19
21
  cattr_accessor :search_attributes
20
22
  cattr_accessor :index_options
23
+ cattr_accessor :sphinx_index
21
24
  end
22
25
 
23
26
  module ClassMethods
@@ -34,7 +37,7 @@ module Mongoid
34
37
  end
35
38
 
36
39
  def internal_sphinx_index
37
- MongoidSphinx::Index.new(self)
40
+ self.sphinx_index ||= MongoidSphinx::Index.new(self)
38
41
  end
39
42
 
40
43
  def has_sphinx_indexes?
@@ -62,22 +65,50 @@ module Mongoid
62
65
  end
63
66
  puts '</sphinx:schema>'
64
67
 
65
- self.all.each do |document|
68
+ self.all.entries.each do |document|
66
69
  sphinx_compatible_id = document['_id'].to_s.to_i - 100000000000000000000000
67
70
  if sphinx_compatible_id > 0
68
71
  puts "<sphinx:document id=\"#{sphinx_compatible_id}\">"
69
72
 
70
73
  puts "<classname>#{self.to_s}</classname>"
71
74
  self.search_fields.each do |key|
72
- puts "<#{key}><![CDATA[#{document.send(key.to_s)}]]></#{key}>"
75
+ if document.respond_to?(key.to_sym)
76
+ if document[key.to_s].is_a?(Array)
77
+ puts "<#{key}><![CDATA[[#{document[key.to_s].join(", ")}]]></#{key}>"
78
+ elsif document[key.to_s].is_a?(Hash)
79
+ entries = []
80
+ document[key.to_s].to_a.each do |entry|
81
+ entries << entry.join(" : ")
82
+ end
83
+ puts "<#{key}><![CDATA[[#{entries.join(", ")}]]></#{key}>"
84
+ else
85
+ puts "<#{key}><![CDATA[[#{document[key.to_s]}]]></#{key}>"
86
+ end
87
+ end
73
88
  end
74
89
  self.search_attributes.each do |key, value|
75
- value = case value
76
- when 'bool' : document[key.to_s] ? 1 : 0
77
- when 'timestamp' : document[key.to_s].to_i
78
- else document[key.to_s].to_s
79
- end
80
- puts "<#{key}>#{value}</#{key}>"
90
+ if document.respond_to?(key.to_sym)
91
+ value = case value
92
+ when 'bool'
93
+ document[key.to_s] ? 1 : 0
94
+ when 'timestamp'
95
+ document[key.to_s].is_a?(Date) ? document[key.to_s].to_time.to_i : document[key.to_s].to_i
96
+ else
97
+ if document[key.to_s].is_a?(Array)
98
+ document[key.to_s].join(", ")
99
+ elsif document[key.to_s].is_a?(Hash)
100
+ entries = []
101
+ document[key.to_s].to_a.each do |entry|
102
+ entries << entry.join(" : ")
103
+ end
104
+ entries.join(", ")
105
+ else
106
+ document[key.to_s].to_s
107
+ end
108
+ end
109
+ end
110
+ puts "<#{key}>#{value}</#{key}>"
111
+ end
81
112
  end
82
113
 
83
114
  puts '</sphinx:document>'
@@ -126,5 +157,38 @@ module Mongoid
126
157
  end
127
158
  end
128
159
 
160
+ def search_ids(id_range, options = {})
161
+ client = MongoidSphinx::Configuration.instance.client
162
+
163
+ if id_range.is_a?(Range)
164
+ client.id_range = id_range
165
+ elsif id_range.is_a?(Fixnum)
166
+ client.id_range = id_range..id_range
167
+ else
168
+ return []
169
+ end
170
+
171
+ client.match_mode = :extended
172
+ client.limit = options[:limit] if options.key?(:limit)
173
+ client.max_matches = options[:max_matches] if options.key?(:max_matches)
174
+
175
+ result = client.query("* @classname #{self.to_s}")
176
+
177
+ if result and result[:status] == 0 and (matches = result[:matches])
178
+ ids = matches.collect do |row|
179
+ (100000000000000000000000 + row[:doc]).to_s rescue nil
180
+ end.compact
181
+
182
+ return ids if options[:raw] or ids.empty?
183
+ return self.find(ids)
184
+ else
185
+ return false
186
+ end
187
+ end
188
+
189
+ private
190
+ def sphinx_id
191
+ self._id.to_s.to_i - 100000000000000000000000
192
+ end
129
193
  end
130
194
  end
@@ -1,3 +1,3 @@
1
1
  module MongoidSphinx #:nodoc
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,69 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mongoid-sphinx
3
- version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 3
10
- version: 0.1.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Matt Hodgson
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-03-14 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- requirement: &id001 !ruby/object:Gem::Requirement
12
+ date: 2011-11-24 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: &70258246962200 !ruby/object:Gem::Requirement
23
17
  none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- hash: 62196421
28
- segments:
29
- - 2
30
- - 0
31
- - 0
32
- - beta
33
- - 19
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
34
21
  version: 2.0.0.beta.19
35
22
  type: :runtime
36
- name: mongoid
37
23
  prerelease: false
38
- version_requirements: *id001
39
- - !ruby/object:Gem::Dependency
40
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70258246962200
25
+ - !ruby/object:Gem::Dependency
26
+ name: riddle
27
+ requirement: &70258246960920 !ruby/object:Gem::Requirement
41
28
  none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 19
46
- segments:
47
- - 1
48
- - 1
49
- - 0
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
50
32
  version: 1.1.0
51
33
  type: :runtime
52
- name: riddle
53
34
  prerelease: false
54
- version_requirements: *id002
35
+ version_requirements: *70258246960920
55
36
  description: A full text indexing extension for MongoDB using Sphinx and Mongoid.
56
- email:
37
+ email:
57
38
  - mhodgson@redbeard-tech.com
58
39
  executables: []
59
-
60
40
  extensions: []
61
-
62
41
  extra_rdoc_files: []
63
-
64
- files:
42
+ files:
65
43
  - lib/mongoid_sphinx/configuration.rb
66
44
  - lib/mongoid_sphinx/context.rb
45
+ - lib/mongoid_sphinx/delta.rb
67
46
  - lib/mongoid_sphinx/index.rb
68
47
  - lib/mongoid_sphinx/mongoid/identity.rb
69
48
  - lib/mongoid_sphinx/mongoid/sphinx.rb
@@ -72,41 +51,31 @@ files:
72
51
  - lib/mongoid_sphinx/version.rb
73
52
  - lib/mongoid_sphinx.rb
74
53
  - README.markdown
75
- has_rdoc: true
76
54
  homepage: http://github.com/redbeard-tech/mongoid-sphinx
77
55
  licenses: []
78
-
79
56
  post_install_message:
80
57
  rdoc_options: []
81
-
82
- require_paths:
58
+ require_paths:
83
59
  - lib
84
- required_ruby_version: !ruby/object:Gem::Requirement
60
+ required_ruby_version: !ruby/object:Gem::Requirement
85
61
  none: false
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- hash: 3
90
- segments:
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ segments:
91
67
  - 0
92
- version: "0"
93
- required_rubygems_version: !ruby/object:Gem::Requirement
68
+ hash: 1605454523821668766
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
70
  none: false
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- hash: 23
99
- segments:
100
- - 1
101
- - 3
102
- - 6
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
103
74
  version: 1.3.6
104
75
  requirements: []
105
-
106
76
  rubyforge_project:
107
- rubygems_version: 1.3.7
77
+ rubygems_version: 1.8.10
108
78
  signing_key:
109
79
  specification_version: 3
110
- summary: A full text indexing extension for MongoDB using Sphinx and Mongoid.
80
+ summary: MongoDB full text search using Sphinx and Mongoid.
111
81
  test_files: []
112
-