mongoid-sphinx 0.1.3 → 0.1.4

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