ultrasphinx 1.8 → 1.9
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -3
- data/CHANGELOG +4 -0
- data/DEPLOYMENT_NOTES +7 -3
- data/Manifest +10 -0
- data/RAKE_TASKS +4 -2
- data/README +35 -18
- data/TODO +0 -1
- data/examples/default.base +24 -19
- data/lib/ultrasphinx.rb +1 -1
- data/lib/ultrasphinx/configure.rb +66 -25
- data/lib/ultrasphinx/core_extensions.rb +10 -1
- data/lib/ultrasphinx/is_indexed.rb +49 -6
- data/lib/ultrasphinx/search.rb +81 -69
- data/lib/ultrasphinx/search/internals.rb +61 -38
- data/lib/ultrasphinx/search/parser.rb +17 -7
- data/lib/ultrasphinx/ultrasphinx.rb +69 -16
- data/tasks/ultrasphinx.rake +47 -29
- data/test/config/ultrasphinx/test.base +50 -21
- data/test/integration/app/app/models/geo/address.rb +2 -1
- data/test/integration/app/app/models/person/user.rb +12 -3
- data/test/integration/app/app/models/seller.rb +2 -1
- data/test/integration/app/config/environment.rb +2 -0
- data/test/integration/app/config/ultrasphinx/default.base +16 -8
- data/test/integration/app/config/ultrasphinx/development.conf +319 -0
- data/test/integration/app/config/ultrasphinx/development.conf.canonical +152 -24
- data/test/integration/app/db/schema.rb +56 -0
- data/test/integration/app/test/fixtures/sellers.yml +1 -1
- data/test/integration/app/test/fixtures/users.yml +1 -1
- data/test/integration/app/test/unit/country_test.rb +8 -0
- data/test/integration/delta_test.rb +39 -0
- data/test/integration/search_test.rb +60 -1
- data/test/integration/spell_test.rb +6 -2
- data/test/profile/benchmark.rb +44 -0
- data/test/test_helper.rb +6 -1
- data/test/unit/parser_test.rb +21 -2
- data/ultrasphinx.gemspec +4 -4
- data/vendor/riddle/README +2 -2
- data/vendor/riddle/lib/riddle.rb +1 -1
- data/vendor/riddle/lib/riddle/client.rb +45 -10
- data/vendor/riddle/spec/fixtures/data/anchor.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/any.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/boolean.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/distinct.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/field_weights.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/group.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/index.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/index_weights.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/phrase.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/rank_mode.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/simple.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/sort.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/update_simple.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/weights.bin +0 -0
- data/vendor/riddle/spec/fixtures/data_generator.php +130 -0
- data/vendor/riddle/spec/fixtures/sphinxapi.php +1066 -0
- data/vendor/riddle/spec/spec_helper.rb +1 -0
- data/vendor/riddle/spec/unit/client_spec.rb +18 -4
- metadata +12 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
@@ -1,3 +1 @@
|
|
1
|
-
U
|
2
|
-
�%�g($�.���#`������h�W����z\_{wo�N��@rf����4�EAʭ?��l��������П�;�g���͠v���
|
3
|
-
�[�>A���"F������3d|�[4�Z������z�mD��E$`sˎ���b�+��*Q�ߩp�R`��#~"��B�T��
|
1
|
+
(Qr��u'�9���_�U؇�4]�;��x�*����oA����[Y�?�.0�,7�˗�K�ƛ8@<�j�':��4|�F����)�ɝ�}a�m��g8E#�D^+(aX]LM�k�|��EL_P�b<�JU$����>��kr��>�Pp!�g ��m�Xy�T� �ZI��M�DB&�K�w����E���W�~�6��=���qO� v$��1!��u�Qȷ�n��5A�ٳ����=V��lz6Il
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
|
2
|
+
v1.9. Delta indexing. ERb now supported in .base files. Allow setting the searched indexes at runtime.
|
3
|
+
|
4
|
+
v1.8.1. Use multifind/multiget for record loading; avoid using HashWithIndifferentAccess internally for speed; other minor performance improvements.
|
5
|
+
|
2
6
|
v1.8. Update client for compatibility with Sphinx 0.9.8 r1112. This is a breaking release! You need to update Sphinx along with Ultrasphinx. Float range bugfix; text faceting on association_include bugfix. Postgres users, please note that the return type of CRC32() has changed to bigint.
|
3
7
|
|
4
8
|
v1.7. Deployment docs. Postgres fixes. Support association_name instead of class_name (Daniel Higginbotham).
|
data/DEPLOYMENT_NOTES
CHANGED
@@ -15,12 +15,16 @@ You will <b>not</b> want to keep the generated <tt>development.conf</tt> in the
|
|
15
15
|
|
16
16
|
It's easy to keep the search daemon and the indexer running in a production environment. Cronjobs are the best way:
|
17
17
|
|
18
|
-
|
19
|
-
rake ultrasphinx:index >> /log/ultrasphinx-index.log 2>&1'
|
18
|
+
*/6 * * * * bash -c 'cd /path/to/production/current/; RAILS_ENV=production \
|
19
|
+
rake ultrasphinx:index:delta >> /log/ultrasphinx-index.log 2>&1'
|
20
|
+
1 4 * * * * bash -c 'cd /path/to/production/current/; RAILS_ENV=production \
|
21
|
+
rake ultrasphinx:index:main >> /log/ultrasphinx-index.log 2>&1'
|
20
22
|
*/3 * * * * bash -c 'cd /path/to/production/current/; RAILS_ENV=production \
|
21
23
|
rake ultrasphinx:daemon:start >> /log/ultrasphinx-daemon.log 2>&1'
|
22
24
|
|
23
|
-
The first line
|
25
|
+
The first line reindexes the delta index every 10 minutes. The second line reindexes the main index once a day at 4am. The third line will try to restart the search daemon every three minutes. If it's already running, nothing happens.
|
26
|
+
|
27
|
+
Of course if you don't have any models with deltas, don't include the <tt>ultrasphinx:index:delta</tt> task.
|
24
28
|
|
25
29
|
If you are under severe memory limitations you might want to manage the daemon with Monit instead, so you can keep a closer eye on it. The search daemon is extremely reliable, so don't bother with fancy monitoring infrastructure unless you're sure you need it.
|
26
30
|
|
data/Manifest
CHANGED
@@ -71,6 +71,7 @@ test/integration/app/config/environments/test.rb
|
|
71
71
|
test/integration/app/config/locomotive.yml
|
72
72
|
test/integration/app/config/routes.rb
|
73
73
|
test/integration/app/config/ultrasphinx/default.base
|
74
|
+
test/integration/app/config/ultrasphinx/development.conf
|
74
75
|
test/integration/app/config/ultrasphinx/development.conf.canonical
|
75
76
|
test/integration/app/db/migrate/001_create_users.rb
|
76
77
|
test/integration/app/db/migrate/002_create_sellers.rb
|
@@ -81,6 +82,7 @@ test/integration/app/db/migrate/006_add_deleted_to_user.rb
|
|
81
82
|
test/integration/app/db/migrate/007_add_lat_and_long_to_address.rb
|
82
83
|
test/integration/app/db/migrate/008_add_mission_statement_to_seller.rb
|
83
84
|
test/integration/app/db/migrate/009_create_countries.rb
|
85
|
+
test/integration/app/db/schema.rb
|
84
86
|
test/integration/app/doc/README_FOR_APP
|
85
87
|
test/integration/app/public/404.html
|
86
88
|
test/integration/app/public/500.html
|
@@ -123,13 +125,16 @@ test/integration/app/test/functional/states_controller_test.rb
|
|
123
125
|
test/integration/app/test/functional/users_controller_test.rb
|
124
126
|
test/integration/app/test/test_helper.rb
|
125
127
|
test/integration/app/test/unit/address_test.rb
|
128
|
+
test/integration/app/test/unit/country_test.rb
|
126
129
|
test/integration/app/test/unit/seller_test.rb
|
127
130
|
test/integration/app/test/unit/state_test.rb
|
128
131
|
test/integration/app/test/unit/user_test.rb
|
129
132
|
test/integration/configure_test.rb
|
133
|
+
test/integration/delta_test.rb
|
130
134
|
test/integration/search_test.rb
|
131
135
|
test/integration/server_test.rb
|
132
136
|
test/integration/spell_test.rb
|
137
|
+
test/profile/benchmark.rb
|
133
138
|
test/setup.rb
|
134
139
|
test/teardown.rb
|
135
140
|
test/test_all.rb
|
@@ -149,6 +154,7 @@ vendor/riddle/spec/fixtures/data/anchor.bin
|
|
149
154
|
vendor/riddle/spec/fixtures/data/any.bin
|
150
155
|
vendor/riddle/spec/fixtures/data/boolean.bin
|
151
156
|
vendor/riddle/spec/fixtures/data/distinct.bin
|
157
|
+
vendor/riddle/spec/fixtures/data/field_weights.bin
|
152
158
|
vendor/riddle/spec/fixtures/data/filter.bin
|
153
159
|
vendor/riddle/spec/fixtures/data/filter_array.bin
|
154
160
|
vendor/riddle/spec/fixtures/data/filter_array_exclude.bin
|
@@ -159,12 +165,16 @@ vendor/riddle/spec/fixtures/data/filter_range.bin
|
|
159
165
|
vendor/riddle/spec/fixtures/data/filter_range_exclude.bin
|
160
166
|
vendor/riddle/spec/fixtures/data/group.bin
|
161
167
|
vendor/riddle/spec/fixtures/data/index.bin
|
168
|
+
vendor/riddle/spec/fixtures/data/index_weights.bin
|
162
169
|
vendor/riddle/spec/fixtures/data/phrase.bin
|
170
|
+
vendor/riddle/spec/fixtures/data/rank_mode.bin
|
163
171
|
vendor/riddle/spec/fixtures/data/simple.bin
|
164
172
|
vendor/riddle/spec/fixtures/data/sort.bin
|
165
173
|
vendor/riddle/spec/fixtures/data/update_simple.bin
|
166
174
|
vendor/riddle/spec/fixtures/data/weights.bin
|
175
|
+
vendor/riddle/spec/fixtures/data_generator.php
|
167
176
|
vendor/riddle/spec/fixtures/sphinx/configuration.erb
|
177
|
+
vendor/riddle/spec/fixtures/sphinxapi.php
|
168
178
|
vendor/riddle/spec/fixtures/sql/conf.example.yml
|
169
179
|
vendor/riddle/spec/fixtures/sql/data.sql
|
170
180
|
vendor/riddle/spec/fixtures/sql/structure.sql
|
data/RAKE_TASKS
CHANGED
@@ -4,7 +4,9 @@
|
|
4
4
|
These Rake tasks are made available to your Rails app:
|
5
5
|
|
6
6
|
<tt>ultrasphinx:configure</tt>:: Rebuild the configuration file for this particular environment.
|
7
|
-
<tt>ultrasphinx:index</tt>:: Reindex
|
7
|
+
<tt>ultrasphinx:index</tt>:: Reindex and rotate all indexes.
|
8
|
+
<tt>ultrasphinx:index:delta</tt>:: Reindex and rotate the delta index.
|
9
|
+
<tt>ultrasphinx:index:main</tt>:: Reindex and rotate the main index.
|
8
10
|
<tt>ultrasphinx:daemon:restart</tt>:: Restart the search daemon.
|
9
11
|
<tt>ultrasphinx:daemon:start</tt>:: Start the search daemon.
|
10
12
|
<tt>ultrasphinx:daemon:stop</tt>:: Stop the search daemon.
|
@@ -12,4 +14,4 @@ These Rake tasks are made available to your Rails app:
|
|
12
14
|
<tt>ultrasphinx:spelling:build</tt>:: Rebuild the custom spelling dictionary. You may need to use <tt>sudo</tt> if your Aspell folder is not writable by the app user.
|
13
15
|
<tt>ultrasphinx:bootstrap</tt>:: Bootstrap a full Sphinx environment by running configure, index, then daemon:start.
|
14
16
|
|
15
|
-
All tasks have shortcuts. Use <tt>us:conf</tt>, <tt>us:
|
17
|
+
All tasks have shortcuts. Use <tt>us:conf</tt>, <tt>us:index</tt>, <tt>us:main</tt>, <tt>us:delta</tt>, <tt>us:restart</tt>, <tt>us:start</tt>, <tt>us:stop</tt>, <tt>us:stat</tt>, <tt>us:spell</tt>, and <tt>us:boot</tt>.
|
data/README
CHANGED
@@ -5,7 +5,7 @@ Ruby on Rails configurator and client to the Sphinx full text search engine.
|
|
5
5
|
|
6
6
|
== License
|
7
7
|
|
8
|
-
Copyright 2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Some portions copyright Pat Allan, distributed under the MIT license, and used with permission. Some portions copyright PJ Hyett and Mislav Marohnić, distributed under the MIT license, and used with permission.
|
8
|
+
Copyright 2007-2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Some portions copyright Pat Allan, distributed under the MIT license, and used with permission. Some portions copyright PJ Hyett and Mislav Marohnić, distributed under the MIT license, and used with permission.
|
9
9
|
|
10
10
|
The public certificate for the gem is here[http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem].
|
11
11
|
|
@@ -14,30 +14,27 @@ If you use this software, please {make a donation}[http://blog.evanweaver.com/do
|
|
14
14
|
== Requirements
|
15
15
|
|
16
16
|
* MySQL 5.0, or PostgreSQL 8.2
|
17
|
-
* Sphinx 0.9.8-
|
17
|
+
* Sphinx 0.9.8-rc1
|
18
18
|
* Rails 2.0.2
|
19
19
|
|
20
20
|
More recent versions than listed are usually ok.
|
21
21
|
|
22
22
|
== Features
|
23
23
|
|
24
|
-
|
24
|
+
Sphinx/Ultrasphinx is the fastest and most stable Rails fulltext search solution.
|
25
|
+
|
26
|
+
Features include:
|
27
|
+
|
25
28
|
* searching and ranking across orthogonal models
|
29
|
+
* delta index support
|
26
30
|
* excerpt highlighting
|
27
|
-
*
|
31
|
+
* Google-style query parser
|
32
|
+
* spellcheck
|
28
33
|
* faceting on text, date, and numeric fields
|
29
|
-
|
30
|
-
ActiveRecord-style SQL generation:
|
34
|
+
* field weighting, merging, and aliases
|
31
35
|
* <tt>belongs_to</tt> and <tt>has_many</tt> includes
|
32
|
-
*
|
33
|
-
*
|
34
|
-
|
35
|
-
Good Rails integration:
|
36
|
-
* automatic memcached loads via <tt>cache_fu</tt>
|
37
|
-
* <tt>will_paginate</tt> compatibility
|
38
|
-
* query spellcheck
|
39
|
-
* Google-style query parser
|
40
|
-
* error recovery
|
36
|
+
* drop-in compatibility with will_paginate[http://err.lighthouseapp.com/projects/466/home]
|
37
|
+
* drop-in compatibility with Interlock[http://blog.evanweaver.com/files/doc/fauna/interlock/]
|
41
38
|
* multiple deployment environments
|
42
39
|
* comprehensive Rake tasks
|
43
40
|
|
@@ -57,7 +54,7 @@ Then, install the plugin:
|
|
57
54
|
|
58
55
|
Next, copy the <tt>examples/default.base</tt> file to <tt>RAILS_ROOT/config/ultrasphinx/default.base</tt>. This file sets up the Sphinx daemon options such as port, host, and index location.
|
59
56
|
|
60
|
-
If you need per-environment configuration, you can use <tt>RAILS_ROOT/config/ultrasphinx/development.base</tt>, etc.
|
57
|
+
If you need per-environment configuration, you can use <tt>RAILS_ROOT/config/ultrasphinx/development.base</tt>, etc. Note that ERb is also allowed within the <tt>.base</tt> files, and can be an alternative way to DRY up multiple configurations.
|
61
58
|
|
62
59
|
Now, in your models, use the <tt>is_indexed</tt> method to configure a model as searchable. For example:
|
63
60
|
|
@@ -91,11 +88,29 @@ For more query options, including excerpt mode, see Ultrasphinx::Search.
|
|
91
88
|
|
92
89
|
== Pagination
|
93
90
|
|
94
|
-
Once the <tt>@search</tt> object has been <tt>run</tt>, it is directly compatible with the <tt>will_paginate</tt> view helper.
|
91
|
+
Once the <tt>@search</tt> object has been <tt>run</tt>, it is directly compatible with the <tt>will_paginate</tt> view helper. In your view, just do:
|
92
|
+
<%= will_paginate(@search) %>
|
95
93
|
|
96
94
|
== Spell checking
|
97
95
|
|
98
96
|
See Ultrasphinx::Spell.
|
97
|
+
|
98
|
+
== Delta indexing
|
99
|
+
|
100
|
+
Delta indexing speeds up your updates by not reindexing the entire dataset every time.
|
101
|
+
|
102
|
+
First, in your <tt>.base</tt> file, set the indexer option <tt>delta</tt> to your maximum interval between full reindexes. A day or a week is good, depending. Add a little bit to account for the time it takes the actual index to run:
|
103
|
+
|
104
|
+
delta = <%= 1.day + 30.minutes %>
|
105
|
+
|
106
|
+
Now, configure your models for delta indexing in the <tt>is_indexed</tt> call:
|
107
|
+
|
108
|
+
is_indexed :fields => ['created_at', 'title', 'body'],
|
109
|
+
:delta => true
|
110
|
+
|
111
|
+
Now you can run <tt>rake ultrasphinx:index:delta</tt> frequently, and only records that were changed within 1 day will be reindexed. You will need to run <tt>rake ultrasphinx:index:main</tt> once a day to move the delta contents into the main index.
|
112
|
+
|
113
|
+
See ActiveRecord::Base .is_indexed and DEPLOYMENT_NOTES[link:files/DEPLOYMENT_NOTES.html] for more.
|
99
114
|
|
100
115
|
== Available Rake tasks
|
101
116
|
|
@@ -105,7 +120,9 @@ See RAKE_TASKS[link:files/RAKE_TASKS.html].
|
|
105
120
|
|
106
121
|
See DEPLOYMENT_NOTES[link:files/DEPLOYMENT_NOTES.html].
|
107
122
|
|
108
|
-
==
|
123
|
+
== Gotchas
|
124
|
+
|
125
|
+
Note that since Ultrasphinx preloads indexed models, you need to make sure those models have their own dependencies in place early in the boot process. This may require adjusting the general plugin load order or moving monkey-patches from <tt>lib/</tt> to <tt>vendor/plugins/</tt>.
|
109
126
|
|
110
127
|
PostgreSQL 8.2 and higher are well supported. However, make sure you have executed <tt>CREATE LANGUAGE plpgsql;</tt> at least once. This step does not need to be repeated, so depending on your DB permissions, you might be able to put it in a migration.
|
111
128
|
|
data/TODO
CHANGED
data/examples/default.base
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# Sphinx/Ultrasphinx user-configurable options.
|
4
4
|
#
|
5
5
|
# Copy this file to RAILS_ROOT/config/ultrasphinx. You can use individual
|
6
|
-
# namespaces if you want (e.g. development.base, production.base,
|
7
|
-
# test.base).
|
6
|
+
# namespaces if you want (e.g. development.base, production.base,
|
7
|
+
# test.base). Note that ERb is also allowed.
|
8
8
|
#
|
9
9
|
# This file should not be handed directly to Sphinx. Use the rake task
|
10
10
|
#
|
@@ -15,56 +15,61 @@
|
|
15
15
|
# to Sphinx.
|
16
16
|
#
|
17
17
|
# It is safe to edit .base files by hand. It is not safe to edit the generated
|
18
|
-
# .conf files. Do not symlink the .conf file to the .base file
|
19
|
-
# people think they need to do that. It's wrong.
|
18
|
+
# .conf files. Do not symlink the .conf file to the .base file; it's wrong.
|
20
19
|
#
|
21
20
|
|
21
|
+
<% path = "/opt/local/var/db/sphinx/" %>
|
22
|
+
|
23
|
+
# Indexing options
|
22
24
|
indexer
|
23
|
-
{
|
24
|
-
# Indexer running options
|
25
|
+
{
|
25
26
|
mem_limit = 256M
|
27
|
+
|
28
|
+
# Ultrasphinx-specific key
|
29
|
+
delta = <%= 1.day + 30.minutes %>
|
26
30
|
}
|
27
31
|
|
32
|
+
# Daemon options
|
28
33
|
searchd
|
29
|
-
{
|
30
|
-
# Daemon options
|
34
|
+
{
|
31
35
|
# What interface the search daemon should listen on and where to store its logs
|
32
36
|
address = 0.0.0.0
|
33
37
|
port = 3312
|
34
38
|
seamless_rotate = 1
|
35
|
-
log =
|
36
|
-
query_log =
|
39
|
+
log = <%= path %>log/searchd.log
|
40
|
+
query_log = <%= path %>log/query.log
|
37
41
|
read_timeout = 5
|
38
42
|
max_children = 300
|
39
|
-
pid_file =
|
43
|
+
pid_file = <%= path %>log/searchd.pid
|
40
44
|
max_matches = 100000
|
41
45
|
}
|
42
46
|
|
47
|
+
# Client options
|
43
48
|
client
|
44
49
|
{
|
45
|
-
# Client options
|
46
50
|
# Name of the Aspell dictionary (two letters max)
|
47
51
|
dictionary_name = ap
|
52
|
+
|
48
53
|
# How your application connects to the search daemon (not necessarily the same as above)
|
49
54
|
server_host = localhost
|
50
55
|
server_port = 3312
|
51
56
|
}
|
52
57
|
|
58
|
+
# Individual SQL source options
|
53
59
|
source
|
54
|
-
{
|
55
|
-
# Individual SQL source options
|
60
|
+
{
|
56
61
|
sql_ranged_throttle = 0
|
57
62
|
sql_range_step = 5000
|
58
63
|
sql_query_post =
|
59
64
|
}
|
60
65
|
|
66
|
+
# Index building options
|
61
67
|
index
|
62
|
-
{
|
63
|
-
|
64
|
-
|
65
|
-
docinfo = extern # just leave this alone
|
68
|
+
{
|
69
|
+
path = <%= path %>
|
70
|
+
docinfo = extern # Just leave this alone
|
66
71
|
morphology = stem_en
|
67
|
-
stopwords = #
|
72
|
+
stopwords = # <%= path %>/ap-stopwords.txt
|
68
73
|
min_word_len = 1
|
69
74
|
|
70
75
|
# HTML-specific options
|
data/lib/ultrasphinx.rb
CHANGED
@@ -17,7 +17,7 @@ require 'ultrasphinx/associations'
|
|
17
17
|
require 'ultrasphinx/core_extensions'
|
18
18
|
require 'ultrasphinx/is_indexed'
|
19
19
|
|
20
|
-
if (ActiveRecord::Base.connection rescue nil) # XXX
|
20
|
+
if (ActiveRecord::Base.connection rescue nil) # XXX Not sure why this needed to be wrapped.
|
21
21
|
require 'ultrasphinx/configure'
|
22
22
|
require 'ultrasphinx/autoload'
|
23
23
|
require 'ultrasphinx/fields'
|
@@ -12,7 +12,7 @@ module Ultrasphinx
|
|
12
12
|
Dir["**/*.rb"].each do |filename|
|
13
13
|
open(filename) do |file|
|
14
14
|
begin
|
15
|
-
if file.grep(
|
15
|
+
if file.grep(/^\s+is_indexed/).any?
|
16
16
|
filename = filename[0..-4]
|
17
17
|
begin
|
18
18
|
File.basename(filename).camelize.constantize
|
@@ -41,21 +41,33 @@ module Ultrasphinx
|
|
41
41
|
|
42
42
|
say "rebuilding configurations for #{RAILS_ENV} environment"
|
43
43
|
say "available models are #{MODEL_CONFIGURATION.keys.to_sentence}"
|
44
|
-
File.open(CONF_PATH, "w") do |conf|
|
45
|
-
|
44
|
+
File.open(CONF_PATH, "w") do |conf|
|
46
45
|
conf.puts global_header
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
46
|
+
say "generating SQL"
|
47
|
+
|
48
|
+
INDEXES.each do |index|
|
49
|
+
sources = []
|
50
|
+
cached_groups = Fields.instance.groups.join("\n")
|
51
|
+
|
52
|
+
MODEL_CONFIGURATION.each_with_index do |model_and_options, class_id|
|
53
|
+
# This relies on hash sort order being deterministic per-machine
|
54
|
+
model, options = model_and_options
|
55
|
+
klass = model.constantize
|
56
|
+
source = "#{model.tableize.gsub('/', '__')}_#{index}"
|
57
|
+
|
58
|
+
if index != DELTA_INDEX or options['delta']
|
59
|
+
# If we are building the delta, we only want to include the models that requested it
|
60
|
+
conf.puts build_source(index, Fields.instance, model, options, class_id, klass, source, cached_groups)
|
61
|
+
sources << source
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if sources.any?
|
66
|
+
# Don't generate a delta index if there are no delta tables
|
67
|
+
conf.puts build_index(index, sources)
|
68
|
+
end
|
69
|
+
|
56
70
|
end
|
57
|
-
|
58
|
-
conf.puts build_index(sources)
|
59
71
|
end
|
60
72
|
end
|
61
73
|
|
@@ -68,7 +80,8 @@ module Ultrasphinx
|
|
68
80
|
["\n# Auto-generated at #{Time.now}.",
|
69
81
|
"# Hand modifications will be overwritten.",
|
70
82
|
"# #{BASE_PATH}\n",
|
71
|
-
INDEXER_SETTINGS._to_conf_string('indexer'),
|
83
|
+
INDEXER_SETTINGS.except('delta')._to_conf_string('indexer'),
|
84
|
+
"",
|
72
85
|
DAEMON_SETTINGS._to_conf_string("searchd")]
|
73
86
|
end
|
74
87
|
|
@@ -86,9 +99,31 @@ module Ultrasphinx
|
|
86
99
|
end
|
87
100
|
conf.sort.join("\n")
|
88
101
|
end
|
102
|
+
|
103
|
+
|
104
|
+
def build_delta_condition(index, klass, options)
|
105
|
+
if index == DELTA_INDEX and options['delta']
|
106
|
+
# Add delta condition if necessary
|
107
|
+
table, field = klass.table_name, options['delta']['field']
|
108
|
+
source_string = "#{table}.#{field}"
|
109
|
+
delta_column = klass.columns_hash[field]
|
110
|
+
|
111
|
+
if delta_column
|
112
|
+
raise ConfigurationError, "#{source_string} is not a :datetime" unless delta_column.type == :datetime
|
113
|
+
if (options['fields'] + options['concatenate'] + options['include']).detect { |entry| entry['sortable'] }
|
114
|
+
# Warning about the sortable problem
|
115
|
+
# XXX Kind of in an odd place, but I want to happen at index time
|
116
|
+
Ultrasphinx.say "warning; text sortable columns on #{klass.name} will return wrong results with partial delta indexing"
|
117
|
+
end
|
118
|
+
string = "#{source_string} > #{SQL_FUNCTIONS[ADAPTER]['delta']._interpolate(INDEXER_SETTINGS['delta'])}";
|
119
|
+
else
|
120
|
+
Ultrasphinx.say "warning; #{klass.name} will reindex the entire table during delta indexing"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
89
124
|
|
90
125
|
|
91
|
-
def setup_source_arrays(klass, fields, class_id, conditions)
|
126
|
+
def setup_source_arrays(index, klass, fields, class_id, conditions)
|
92
127
|
condition_strings = Array(conditions).map do |condition|
|
93
128
|
"(#{condition})"
|
94
129
|
end
|
@@ -101,12 +136,13 @@ module Ultrasphinx
|
|
101
136
|
end
|
102
137
|
|
103
138
|
|
104
|
-
def range_select_string(klass)
|
139
|
+
def range_select_string(klass, delta_condition)
|
105
140
|
["sql_query_range = SELECT",
|
106
141
|
SQL_FUNCTIONS[ADAPTER]['range_cast']._interpolate("MIN(#{klass.primary_key})"),
|
107
|
-
",
|
142
|
+
",",
|
108
143
|
SQL_FUNCTIONS[ADAPTER]['range_cast']._interpolate("MAX(#{klass.primary_key})"),
|
109
|
-
"FROM #{klass.table_name}"
|
144
|
+
"FROM #{klass.table_name}",
|
145
|
+
("WHERE #{delta_condition}" if delta_condition),
|
110
146
|
].join(" ")
|
111
147
|
end
|
112
148
|
|
@@ -116,11 +152,16 @@ module Ultrasphinx
|
|
116
152
|
end
|
117
153
|
|
118
154
|
|
119
|
-
def build_source(fields, model, options, class_id, klass, source, groups)
|
155
|
+
def build_source(index, fields, model, options, class_id, klass, source, groups)
|
120
156
|
|
121
157
|
column_strings, join_strings, condition_strings, group_bys, use_distinct, remaining_columns =
|
122
158
|
setup_source_arrays(
|
123
|
-
klass, fields, class_id, options['conditions'])
|
159
|
+
index, klass, fields, class_id, options['conditions'])
|
160
|
+
|
161
|
+
delta_condition =
|
162
|
+
build_delta_condition(
|
163
|
+
index, klass, options)
|
164
|
+
condition_strings << delta_condition if delta_condition
|
124
165
|
|
125
166
|
column_strings, join_strings, group_bys, remaining_columns =
|
126
167
|
build_regular_fields(
|
@@ -140,7 +181,7 @@ module Ultrasphinx
|
|
140
181
|
"source #{source}\n{",
|
141
182
|
SOURCE_SETTINGS._to_conf_string,
|
142
183
|
setup_source_database(klass),
|
143
|
-
range_select_string(klass),
|
184
|
+
range_select_string(klass, delta_condition),
|
144
185
|
build_query(klass, column_strings, join_strings, condition_strings, use_distinct, group_bys),
|
145
186
|
"\n" + groups,
|
146
187
|
query_info_string(klass, class_id),
|
@@ -271,13 +312,13 @@ module Ultrasphinx
|
|
271
312
|
end
|
272
313
|
|
273
314
|
|
274
|
-
def build_index(sources)
|
315
|
+
def build_index(index, sources)
|
275
316
|
["\n# Index configuration\n\n",
|
276
|
-
"index #{
|
317
|
+
"index #{index}\n{",
|
277
318
|
sources.sort.map do |source|
|
278
319
|
" source = #{source}"
|
279
320
|
end.join("\n"),
|
280
|
-
INDEX_SETTINGS.merge('path' => INDEX_SETTINGS['path'] + "/sphinx_index_#{
|
321
|
+
INDEX_SETTINGS.merge('path' => INDEX_SETTINGS['path'] + "/sphinx_index_#{index}")._to_conf_string,
|
281
322
|
"}\n\n"]
|
282
323
|
end
|
283
324
|
|