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.
- data/lib/mongoid_sphinx.rb +2 -2
- data/lib/mongoid_sphinx/configuration.rb +44 -11
- data/lib/mongoid_sphinx/delta.rb +74 -0
- data/lib/mongoid_sphinx/index.rb +9 -1
- data/lib/mongoid_sphinx/mongoid/sphinx.rb +82 -18
- data/lib/mongoid_sphinx/version.rb +1 -1
- metadata +38 -69
data/lib/mongoid_sphinx.rb
CHANGED
@@ -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 = "#{
|
29
|
-
@configuration.searchd.log = "#{
|
30
|
-
@configuration.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, "#{
|
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 = "#{
|
37
|
-
self.
|
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 = "#{
|
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)[
|
165
|
+
conf = YAML::load(ERB.new(IO.read(path)).result)[@env]
|
163
166
|
|
164
|
-
conf.
|
165
|
-
|
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
|
data/lib/mongoid_sphinx/index.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
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
|
-
|
5
|
-
prerelease:
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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: *
|
39
|
-
- !ruby/object:Gem::Dependency
|
40
|
-
|
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: *
|
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
|
-
|
90
|
-
segments:
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
segments:
|
91
67
|
- 0
|
92
|
-
|
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.
|
77
|
+
rubygems_version: 1.8.10
|
108
78
|
signing_key:
|
109
79
|
specification_version: 3
|
110
|
-
summary:
|
80
|
+
summary: MongoDB full text search using Sphinx and Mongoid.
|
111
81
|
test_files: []
|
112
|
-
|