acts_as_solr 1.0.0
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/.gitignore +8 -0
- data/CHANGE_LOG +233 -0
- data/FORKED_CHANGES +3 -0
- data/LICENSE +19 -0
- data/README.markdown +94 -0
- data/README.rdoc +84 -0
- data/Rakefile +57 -0
- data/TESTING_THE_PLUGIN +25 -0
- data/VERSION +1 -0
- data/acts_as_solr.gemspec +237 -0
- data/config/solr.yml +15 -0
- data/config/solr_environment.rb +22 -0
- data/init.rb +21 -0
- data/install.rb +11 -0
- data/lib/acts_as_solr.rb +61 -0
- data/lib/acts_methods.rb +284 -0
- data/lib/class_methods.rb +239 -0
- data/lib/common_methods.rb +89 -0
- data/lib/deprecation.rb +61 -0
- data/lib/instance_methods.rb +181 -0
- data/lib/lazy_document.rb +18 -0
- data/lib/parser_methods.rb +230 -0
- data/lib/search_results.rb +69 -0
- data/lib/solr/connection.rb +191 -0
- data/lib/solr/document.rb +78 -0
- data/lib/solr/exception.rb +13 -0
- data/lib/solr/field.rb +39 -0
- data/lib/solr/importer/array_mapper.rb +26 -0
- data/lib/solr/importer/delimited_file_source.rb +38 -0
- data/lib/solr/importer/hpricot_mapper.rb +27 -0
- data/lib/solr/importer/mapper.rb +51 -0
- data/lib/solr/importer/solr_source.rb +43 -0
- data/lib/solr/importer/xpath_mapper.rb +35 -0
- data/lib/solr/importer.rb +19 -0
- data/lib/solr/indexer.rb +52 -0
- data/lib/solr/request/add_document.rb +63 -0
- data/lib/solr/request/base.rb +36 -0
- data/lib/solr/request/commit.rb +31 -0
- data/lib/solr/request/delete.rb +50 -0
- data/lib/solr/request/dismax.rb +46 -0
- data/lib/solr/request/index_info.rb +22 -0
- data/lib/solr/request/modify_document.rb +51 -0
- data/lib/solr/request/optimize.rb +21 -0
- data/lib/solr/request/ping.rb +36 -0
- data/lib/solr/request/select.rb +56 -0
- data/lib/solr/request/spellcheck.rb +30 -0
- data/lib/solr/request/standard.rb +402 -0
- data/lib/solr/request/update.rb +23 -0
- data/lib/solr/request.rb +26 -0
- data/lib/solr/response/add_document.rb +17 -0
- data/lib/solr/response/base.rb +42 -0
- data/lib/solr/response/commit.rb +17 -0
- data/lib/solr/response/delete.rb +13 -0
- data/lib/solr/response/dismax.rb +8 -0
- data/lib/solr/response/index_info.rb +26 -0
- data/lib/solr/response/modify_document.rb +17 -0
- data/lib/solr/response/optimize.rb +14 -0
- data/lib/solr/response/ping.rb +28 -0
- data/lib/solr/response/ruby.rb +42 -0
- data/lib/solr/response/select.rb +17 -0
- data/lib/solr/response/spellcheck.rb +20 -0
- data/lib/solr/response/standard.rb +64 -0
- data/lib/solr/response/xml.rb +42 -0
- data/lib/solr/response.rb +27 -0
- data/lib/solr/solrtasks.rb +27 -0
- data/lib/solr/util.rb +32 -0
- data/lib/solr/xml.rb +44 -0
- data/lib/solr.rb +21 -0
- data/lib/solr_fixtures.rb +13 -0
- data/lib/tasks/database.rake +18 -0
- data/lib/tasks/solr.rake +137 -0
- data/lib/tasks/test.rake +7 -0
- data/lib/will_paginate_support.rb +12 -0
- data/solr/CHANGES.txt +1207 -0
- data/solr/LICENSE.txt +712 -0
- data/solr/NOTICE.txt +90 -0
- data/solr/etc/jetty.xml +205 -0
- data/solr/etc/webdefault.xml +379 -0
- data/solr/lib/easymock.jar +0 -0
- data/solr/lib/jetty-6.1.3.jar +0 -0
- data/solr/lib/jetty-util-6.1.3.jar +0 -0
- data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr/lib/servlet-api-2.4.jar +0 -0
- data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr/lib/xpp3-1.1.3.4.O.jar +0 -0
- data/solr/logs/.empty-dir-for-git +0 -0
- data/solr/solr/README.txt +52 -0
- data/solr/solr/bin/abc +176 -0
- data/solr/solr/bin/abo +176 -0
- data/solr/solr/bin/backup +108 -0
- data/solr/solr/bin/backupcleaner +142 -0
- data/solr/solr/bin/commit +128 -0
- data/solr/solr/bin/optimize +129 -0
- data/solr/solr/bin/readercycle +129 -0
- data/solr/solr/bin/rsyncd-disable +77 -0
- data/solr/solr/bin/rsyncd-enable +76 -0
- data/solr/solr/bin/rsyncd-start +145 -0
- data/solr/solr/bin/rsyncd-stop +105 -0
- data/solr/solr/bin/scripts-util +83 -0
- data/solr/solr/bin/snapcleaner +148 -0
- data/solr/solr/bin/snapinstaller +168 -0
- data/solr/solr/bin/snappuller +248 -0
- data/solr/solr/bin/snappuller-disable +77 -0
- data/solr/solr/bin/snappuller-enable +77 -0
- data/solr/solr/bin/snapshooter +109 -0
- data/solr/solr/conf/admin-extra.html +31 -0
- data/solr/solr/conf/protwords.txt +21 -0
- data/solr/solr/conf/schema.xml +126 -0
- data/solr/solr/conf/scripts.conf +24 -0
- data/solr/solr/conf/solrconfig.xml +458 -0
- data/solr/solr/conf/stopwords.txt +57 -0
- data/solr/solr/conf/synonyms.txt +31 -0
- data/solr/solr/conf/xslt/example.xsl +132 -0
- data/solr/solr/conf/xslt/example_atom.xsl +63 -0
- data/solr/solr/conf/xslt/example_rss.xsl +62 -0
- data/solr/start.jar +0 -0
- data/solr/tmp/.empty-dir-for-git +0 -0
- data/solr/webapps/solr.war +0 -0
- data/test/config/solr.yml +2 -0
- data/test/db/connections/mysql/connection.rb +10 -0
- data/test/db/connections/sqlite/connection.rb +8 -0
- data/test/db/migrate/001_create_books.rb +15 -0
- data/test/db/migrate/002_create_movies.rb +12 -0
- data/test/db/migrate/003_create_categories.rb +11 -0
- data/test/db/migrate/004_create_electronics.rb +16 -0
- data/test/db/migrate/005_create_authors.rb +12 -0
- data/test/db/migrate/006_create_postings.rb +9 -0
- data/test/db/migrate/007_create_posts.rb +13 -0
- data/test/db/migrate/008_create_gadgets.rb +11 -0
- data/test/fixtures/authors.yml +9 -0
- data/test/fixtures/books.yml +13 -0
- data/test/fixtures/categories.yml +7 -0
- data/test/fixtures/db_definitions/mysql.sql +41 -0
- data/test/fixtures/electronics.yml +49 -0
- data/test/fixtures/movies.yml +9 -0
- data/test/fixtures/postings.yml +10 -0
- data/test/functional/acts_as_solr_test.rb +413 -0
- data/test/functional/association_indexing_test.rb +37 -0
- data/test/functional/faceted_search_test.rb +163 -0
- data/test/functional/multi_solr_search_test.rb +51 -0
- data/test/models/author.rb +10 -0
- data/test/models/book.rb +10 -0
- data/test/models/category.rb +8 -0
- data/test/models/electronic.rb +21 -0
- data/test/models/gadget.rb +9 -0
- data/test/models/movie.rb +17 -0
- data/test/models/novel.rb +2 -0
- data/test/models/post.rb +3 -0
- data/test/models/posting.rb +11 -0
- data/test/test_helper.rb +51 -0
- data/test/unit/acts_methods_shoulda.rb +70 -0
- data/test/unit/class_methods_shoulda.rb +90 -0
- data/test/unit/common_methods_shoulda.rb +112 -0
- data/test/unit/instance_methods_shoulda.rb +326 -0
- data/test/unit/lazy_document_shoulda.rb +35 -0
- data/test/unit/parser_instance.rb +19 -0
- data/test/unit/parser_methods_shoulda.rb +279 -0
- data/test/unit/solr_instance.rb +46 -0
- data/test/unit/test_helper.rb +26 -0
- metadata +259 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
class Solr::Response::Select < Solr::Response::Ruby
|
|
14
|
+
def initialize(ruby_code)
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
class Solr::Response::Spellcheck < Solr::Response::Ruby
|
|
14
|
+
attr_reader :suggestions
|
|
15
|
+
|
|
16
|
+
def initialize(ruby_code)
|
|
17
|
+
super
|
|
18
|
+
@suggestions = @data['suggestions']
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
class Solr::Response::Standard < Solr::Response::Ruby
|
|
14
|
+
FacetValue = Struct.new(:name, :value)
|
|
15
|
+
include Enumerable
|
|
16
|
+
|
|
17
|
+
def initialize(ruby_code)
|
|
18
|
+
super
|
|
19
|
+
@response = @data['response']
|
|
20
|
+
raise "response section missing" unless @response.kind_of? Hash
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def total_hits
|
|
24
|
+
@response['numFound']
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def start
|
|
28
|
+
@response['start']
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def hits
|
|
32
|
+
@response['docs']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def max_score
|
|
36
|
+
@response['maxScore']
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# TODO: consider the use of json.nl parameter
|
|
40
|
+
def field_facets(field)
|
|
41
|
+
facets = []
|
|
42
|
+
values = @data['facet_counts']['facet_fields'][field]
|
|
43
|
+
Solr::Util.paired_array_each(values) do |key, value|
|
|
44
|
+
facets << FacetValue.new(key, value)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
facets
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def highlighted(id, field)
|
|
51
|
+
@data['highlighting'][id.to_s][field.to_s] rescue nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def highlighting
|
|
55
|
+
@data['highlighting']
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# supports enumeration of hits
|
|
59
|
+
# TODO revisit - should this iterate through *all* hits by re-requesting more?
|
|
60
|
+
def each
|
|
61
|
+
@response['docs'].each {|hit| yield hit}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
require 'rexml/document'
|
|
14
|
+
require 'solr/exception'
|
|
15
|
+
|
|
16
|
+
class Solr::Response::Xml < Solr::Response::Base
|
|
17
|
+
attr_reader :doc, :status_code, :status_message
|
|
18
|
+
|
|
19
|
+
def initialize(xml)
|
|
20
|
+
super
|
|
21
|
+
# parse the xml
|
|
22
|
+
@doc = REXML::Document.new(xml)
|
|
23
|
+
|
|
24
|
+
# look for the result code and string
|
|
25
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
|
26
|
+
# <response>
|
|
27
|
+
# <lst name="responseHeader"><int name="status">0</int><int name="QTime">2</int></lst>
|
|
28
|
+
# </response>
|
|
29
|
+
result = REXML::XPath.first(@doc, './response/lst[@name="responseHeader"]/int[@name="status"]')
|
|
30
|
+
if result
|
|
31
|
+
@status_code = result.text
|
|
32
|
+
@status_message = result.text # TODO: any need for a message?
|
|
33
|
+
end
|
|
34
|
+
rescue REXML::ParseException => e
|
|
35
|
+
raise Solr::Exception.new("invalid response xml: #{e}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ok?
|
|
39
|
+
return @status_code == '0'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
module Solr; module Response; end; end
|
|
14
|
+
require 'solr/response/base'
|
|
15
|
+
require 'solr/response/xml'
|
|
16
|
+
require 'solr/response/ruby'
|
|
17
|
+
require 'solr/response/ping'
|
|
18
|
+
require 'solr/response/add_document'
|
|
19
|
+
require 'solr/response/modify_document'
|
|
20
|
+
require 'solr/response/standard'
|
|
21
|
+
require 'solr/response/spellcheck'
|
|
22
|
+
require 'solr/response/dismax'
|
|
23
|
+
require 'solr/response/commit'
|
|
24
|
+
require 'solr/response/delete'
|
|
25
|
+
require 'solr/response/index_info'
|
|
26
|
+
require 'solr/response/optimize'
|
|
27
|
+
require 'solr/response/select'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
3
|
+
# (the "License"); you may not use this file except in compliance with
|
|
4
|
+
# the License. You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
# TODO: fill out Solr tasks: start, stop, ping, optimize, etc.
|
|
15
|
+
|
|
16
|
+
require 'rake'
|
|
17
|
+
require 'rake/tasklib'
|
|
18
|
+
|
|
19
|
+
module Solr
|
|
20
|
+
namespace :solr do
|
|
21
|
+
desc "Start Solr"
|
|
22
|
+
task :start do
|
|
23
|
+
# TODO: actually start it up!
|
|
24
|
+
puts "Starting..."
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/solr/util.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
class Solr::Util
|
|
14
|
+
# paired_array_each([key1,value1,key2,value2]) yields twice:
|
|
15
|
+
# |key1,value1| and |key2,value2|
|
|
16
|
+
def self.paired_array_each(a, &block)
|
|
17
|
+
0.upto(a.size / 2 - 1) do |i|
|
|
18
|
+
n = i * 2
|
|
19
|
+
yield(a[n], a[n+1])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# paired_array_to_hash([key1,value1,key2,value2]) => {key1 => value1, key2, value2}
|
|
24
|
+
def self.paired_array_to_hash(a)
|
|
25
|
+
Hash[*a]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.query_parser_escape(string)
|
|
29
|
+
# backslash prefix everything that isn't a word character
|
|
30
|
+
string.gsub(/(\W)/,'\\\\\1')
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/solr/xml.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
module Solr::XML
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
|
|
18
|
+
# If we can load rubygems and libxml-ruby...
|
|
19
|
+
require 'rubygems'
|
|
20
|
+
require 'xml/libxml'
|
|
21
|
+
raise "acts_as_solr requires libxml-ruby 0.7 or greater" unless XML::Node.public_instance_methods.include?("attributes")
|
|
22
|
+
|
|
23
|
+
# then make a few modifications to XML::Node so it can stand in for REXML::Element
|
|
24
|
+
class XML::Node
|
|
25
|
+
# element.add_element(another_element) should work
|
|
26
|
+
alias_method :add_element, :<<
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# element.text = "blah" should work
|
|
30
|
+
def text=(x)
|
|
31
|
+
self << x.to_s
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# And use XML::Node for our XML generation
|
|
36
|
+
Solr::XML::Element = XML::Node
|
|
37
|
+
|
|
38
|
+
rescue LoadError => e # If we can't load either rubygems or libxml-ruby
|
|
39
|
+
puts "Requiring REXML"
|
|
40
|
+
# Just use REXML.
|
|
41
|
+
require 'rexml/document'
|
|
42
|
+
Solr::XML::Element = REXML::Element
|
|
43
|
+
|
|
44
|
+
end
|
data/lib/solr.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
module Solr; end
|
|
14
|
+
require 'solr/exception'
|
|
15
|
+
require 'solr/request'
|
|
16
|
+
require 'solr/connection'
|
|
17
|
+
require 'solr/response'
|
|
18
|
+
require 'solr/util'
|
|
19
|
+
require 'solr/xml'
|
|
20
|
+
require 'solr/importer'
|
|
21
|
+
require 'solr/indexer'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ActsAsSolr
|
|
2
|
+
|
|
3
|
+
class SolrFixtures
|
|
4
|
+
def self.load(table_names)
|
|
5
|
+
[table_names].flatten.map { |n| n.to_s }.each do |table_name|
|
|
6
|
+
klass = instance_eval(File.split(table_name.to_s).last.to_s.gsub('_',' ').split(" ").collect{|w| w.capitalize}.to_s.singularize)
|
|
7
|
+
klass.rebuild_solr_index if klass.respond_to?(:rebuild_solr_index)
|
|
8
|
+
end
|
|
9
|
+
ActsAsSolr::Post.execute(Solr::Request::Commit.new)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../solr_fixtures'
|
|
2
|
+
|
|
3
|
+
namespace :db do
|
|
4
|
+
namespace :fixtures do
|
|
5
|
+
desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
|
6
|
+
task :load => :environment do
|
|
7
|
+
begin
|
|
8
|
+
ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => "*:*"))
|
|
9
|
+
ActsAsSolr::Post.execute(Solr::Request::Commit.new)
|
|
10
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
|
11
|
+
ActsAsSolr::SolrFixtures.load(File.basename(fixture_file, '.*'))
|
|
12
|
+
end
|
|
13
|
+
puts "The fixtures loaded have been added to Solr"
|
|
14
|
+
rescue
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/tasks/solr.rake
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'active_record'
|
|
5
|
+
|
|
6
|
+
namespace :solr do
|
|
7
|
+
|
|
8
|
+
desc 'Starts Solr. Options accepted: RAILS_ENV=your_env, PORT=XX. Defaults to development if none.'
|
|
9
|
+
task :start do
|
|
10
|
+
require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
|
|
11
|
+
begin
|
|
12
|
+
n = Net::HTTP.new('127.0.0.1', SOLR_PORT)
|
|
13
|
+
n.request_head('/').value
|
|
14
|
+
|
|
15
|
+
rescue Net::HTTPServerException #responding
|
|
16
|
+
puts "Port #{SOLR_PORT} in use" and return
|
|
17
|
+
|
|
18
|
+
rescue Errno::ECONNREFUSED #not responding
|
|
19
|
+
Dir.chdir(SOLR_PATH) do
|
|
20
|
+
pid = fork do
|
|
21
|
+
#STDERR.close
|
|
22
|
+
exec "java #{SOLR_JVM_OPTIONS} -Dsolr.data.dir=#{SOLR_DATA_PATH} -Djetty.logs=#{SOLR_LOGS_PATH} -Djetty.port=#{SOLR_PORT} -jar start.jar"
|
|
23
|
+
end
|
|
24
|
+
sleep(5)
|
|
25
|
+
File.open("#{SOLR_PIDS_PATH}/#{ENV['RAILS_ENV']}_pid", "w"){ |f| f << pid}
|
|
26
|
+
puts "#{ENV['RAILS_ENV']} Solr started successfully on #{SOLR_PORT}, pid: #{pid}."
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc 'Stops Solr. Specify the environment by using: RAILS_ENV=your_env. Defaults to development if none.'
|
|
32
|
+
task :stop do
|
|
33
|
+
require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
|
|
34
|
+
fork do
|
|
35
|
+
file_path = "#{SOLR_PIDS_PATH}/#{ENV['RAILS_ENV']}_pid"
|
|
36
|
+
if File.exists?(file_path)
|
|
37
|
+
File.open(file_path, "r") do |f|
|
|
38
|
+
pid = f.readline
|
|
39
|
+
Process.kill('TERM', pid.to_i)
|
|
40
|
+
end
|
|
41
|
+
File.unlink(file_path)
|
|
42
|
+
Rake::Task["solr:destroy_index"].invoke if ENV['RAILS_ENV'] == 'test'
|
|
43
|
+
puts "Solr shutdown successfully."
|
|
44
|
+
else
|
|
45
|
+
puts "PID file not found at #{file_path}. Either Solr is not running or no PID file was written."
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
desc 'Remove Solr index'
|
|
51
|
+
task :destroy_index do
|
|
52
|
+
require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
|
|
53
|
+
raise "In production mode. I'm not going to delete the index, sorry." if ENV['RAILS_ENV'] == "production"
|
|
54
|
+
if File.exists?("#{SOLR_DATA_PATH}")
|
|
55
|
+
Dir["#{SOLR_DATA_PATH}/index/*"].each{|f| File.unlink(f)}
|
|
56
|
+
Dir.rmdir("#{SOLR_DATA_PATH}/index")
|
|
57
|
+
puts "Index files removed under " + ENV['RAILS_ENV'] + " environment"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# this task is by Henrik Nyh
|
|
62
|
+
# http://henrik.nyh.se/2007/06/rake-task-to-reindex-models-for-acts_as_solr
|
|
63
|
+
desc %{Reindexes data for all acts_as_solr models. Clears index first to get rid of orphaned records and optimizes index afterwards. RAILS_ENV=your_env to set environment. ONLY=book,person,magazine to only reindex those models; EXCEPT=book,magazine to exclude those models. START_SERVER=true to solr:start before and solr:stop after. BATCH=123 to post/commit in batches of that size: default is 300. CLEAR=false to not clear the index first; OPTIMIZE=false to not optimize the index afterwards.}
|
|
64
|
+
task :reindex => :environment do
|
|
65
|
+
require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
|
|
66
|
+
|
|
67
|
+
includes = env_array_to_constants('ONLY')
|
|
68
|
+
if includes.empty?
|
|
69
|
+
includes = Dir.glob("#{RAILS_ROOT}/app/models/*.rb").map { |path| File.basename(path, ".rb").camelize.constantize }
|
|
70
|
+
end
|
|
71
|
+
excludes = env_array_to_constants('EXCEPT')
|
|
72
|
+
includes -= excludes
|
|
73
|
+
|
|
74
|
+
optimize = env_to_bool('OPTIMIZE', true)
|
|
75
|
+
start_server = env_to_bool('START_SERVER', false)
|
|
76
|
+
clear_first = env_to_bool('CLEAR', true)
|
|
77
|
+
batch_size = ENV['BATCH'].to_i.nonzero? || 300
|
|
78
|
+
debug_output = env_to_bool("DEBUG", false)
|
|
79
|
+
|
|
80
|
+
RAILS_DEFAULT_LOGGER.level = ActiveSupport::BufferedLogger::INFO unless debug_output
|
|
81
|
+
|
|
82
|
+
if start_server
|
|
83
|
+
puts "Starting Solr server..."
|
|
84
|
+
Rake::Task["solr:start"].invoke
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Disable solr_optimize
|
|
88
|
+
module ActsAsSolr::CommonMethods
|
|
89
|
+
def blank() end
|
|
90
|
+
alias_method :deferred_solr_optimize, :solr_optimize
|
|
91
|
+
alias_method :solr_optimize, :blank
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
models = includes.select { |m| m.respond_to?(:rebuild_solr_index) }
|
|
95
|
+
models.each do |model|
|
|
96
|
+
|
|
97
|
+
if clear_first
|
|
98
|
+
puts "Clearing index for #{model}..."
|
|
99
|
+
ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => "#{model.solr_configuration[:type_field]}:#{model}"))
|
|
100
|
+
ActsAsSolr::Post.execute(Solr::Request::Commit.new)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
puts "Rebuilding index for #{model}..."
|
|
104
|
+
model.rebuild_solr_index(batch_size)
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if models.empty?
|
|
109
|
+
puts "There were no models to reindex."
|
|
110
|
+
elsif optimize
|
|
111
|
+
puts "Optimizing..."
|
|
112
|
+
models.last.deferred_solr_optimize
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
if start_server
|
|
116
|
+
puts "Shutting down Solr server..."
|
|
117
|
+
Rake::Task["solr:stop"].invoke
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def env_array_to_constants(env)
|
|
123
|
+
env = ENV[env] || ''
|
|
124
|
+
env.split(/\s*,\s*/).map { |m| m.singularize.camelize.constantize }.uniq
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def env_to_bool(env, default)
|
|
128
|
+
env = ENV[env] || ''
|
|
129
|
+
case env
|
|
130
|
+
when /^true$/i then true
|
|
131
|
+
when /^false$/i then false
|
|
132
|
+
else default
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
|
data/lib/tasks/test.rake
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ActsAsSolr
|
|
2
|
+
module ClassMethods
|
|
3
|
+
def paginate_by_solr(query, options = {})
|
|
4
|
+
options[:total_entries] ||= count_by_solr(query)
|
|
5
|
+
method_missing :paginate_by_solr, query, options
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def find_all_by_solr(*args)
|
|
9
|
+
find_by_solr(*args).records
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|