multi-solr 01.01.05
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/lib/multi_solr/base_searcher.rb +393 -0
- data/lib/multi_solr/filter_value_composite.rb +33 -0
- data/lib/multi_solr/rails_form_render_helper.rb +84 -0
- data/lib/multi_solr/search_request.rb +209 -0
- data/lib/multi_solr/search_result.rb +127 -0
- data/lib/multi_solr/single_core_handler.rb +341 -0
- data/lib/multi_solr/solr_filter_collection.rb +97 -0
- data/lib/multi_solr/solr_filter_date.rb +46 -0
- data/lib/multi_solr/solr_filter_date_range.rb +62 -0
- data/lib/multi_solr/solr_filter_free_query.rb +11 -0
- data/lib/multi_solr/solr_filter_simple.rb +96 -0
- data/lib/multi_solr/timeline_core_handler.rb +131 -0
- data/lib/multi_solr/version.rb +3 -0
- data/lib/multi_solr.rb +43 -0
- data/multi-solr.gemspec +28 -0
- data/spec/fixtures/solr-testdata.yml +13 -0
- data/spec/multi_solr/base_searcher_spec.rb +212 -0
- data/spec/multi_solr/search_request_spec.rb +45 -0
- data/spec/multi_solr/search_result_spec.rb +113 -0
- data/spec/multi_solr/single_core_handler_spec.rb +169 -0
- data/spec/multi_solr/timeline_core_handler_spec.rb +107 -0
- data/spec/solr_test_helper.rb +15 -0
- data/spec/solr_testdata_provider.rb +89 -0
- data/spec/spec_helper.rb +27 -0
- data/test-solr/.gitignore +4 -0
- data/test-solr/articles.xml +6 -0
- data/test-solr/etc/jetty.xml +227 -0
- data/test-solr/etc/webdefault.xml +410 -0
- data/test-solr/lib/jetty-6.1.26-patched-JETTY-1340.jar +0 -0
- data/test-solr/lib/jetty-LICENSE.txt +202 -0
- data/test-solr/lib/jetty-NOTICE.txt +36 -0
- data/test-solr/lib/jetty-util-6.1.26-patched-JETTY-1340.jar +0 -0
- data/test-solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/test-solr/lib/jsp-2.1/jsp-2.1-glassfish-2.1.v20091210.jar +0 -0
- data/test-solr/lib/jsp-2.1/jsp-2.1-jetty-6.1.26.jar +0 -0
- data/test-solr/lib/jsp-2.1/jsp-api-2.1-glassfish-2.1.v20091210.jar +0 -0
- data/test-solr/lib/lukeall-3.4.0_1.jar +0 -0
- data/test-solr/lib/servlet-api-2.5-20081211.jar +0 -0
- data/test-solr/solr/lib/apache-solr-dataimporthandler-3.4.0.jar +0 -0
- data/test-solr/solr/solr.xml +20 -0
- data/test-solr/solr/testcore/conf/dataimport-test.xml +12 -0
- data/test-solr/solr/testcore/conf/schema.xml +42 -0
- data/test-solr/solr/testcore/conf/solr_schema.css +58 -0
- data/test-solr/solr/testcore/conf/solr_schema.xsl +72 -0
- data/test-solr/solr/testcore/conf/solrconfig.xml +72 -0
- data/test-solr/start-test-solr.sh +10 -0
- data/test-solr/start.jar +0 -0
- data/test-solr/webapps/solr.war +0 -0
- metadata +212 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
# Filter für einfachen Wert mit Wertebereich als Collection
|
2
|
+
# und Darstellung als Select-Box.
|
3
|
+
# Der Wertebereich wird dabei über eine FacetSuche ermittelt (per Methode 'list_possible_values' des Searchers)
|
4
|
+
#
|
5
|
+
class MultiSolr::SolrFilterCollection < MultiSolr::SolrFilterSimple
|
6
|
+
|
7
|
+
# Constructor des Filters
|
8
|
+
# Params:
|
9
|
+
# filter_name: Name des Filters als Symbol
|
10
|
+
# options: optionale Hash mit den folgenden Optionen (sind alle optional):
|
11
|
+
# :render_value siehe Optionen bei MultiSolr::SolrFilterSimple.initialize
|
12
|
+
# :solr_query siehe Optionen bei MultiSolr::SolrFilterSimple.initialize
|
13
|
+
# :collection_data: Proc, welches den Wertebereich(Array) liefert
|
14
|
+
# Wenn nicht angegeben, dann wird per 'Searcher.list_possible_values'
|
15
|
+
# mit den Name des Filters der Wertebereich ermittelt.
|
16
|
+
# Das Proc bekommt den Such-Context(Hash) als Parameter (enthält i.a. Searcher und force-query-params).
|
17
|
+
# Beispiel: :collection_data => lambda{|context| (2..10).to_a }
|
18
|
+
# :after_collect: optionales Proc, welches den Wertebereich(Array) nachbearbeitet
|
19
|
+
# Das Proc bekommt den Wertebereich(Array) als Parameter
|
20
|
+
# Beispiel: :after_collect => lambda{|data| MasterData::LockType.cached_find_for_short_names(data).map{|l| [l.full_label, l.short_name] } }
|
21
|
+
#
|
22
|
+
def initialize filter_name, options={}
|
23
|
+
@collection_proc = options.delete(:collection_data)
|
24
|
+
@after_collect_proc = options.delete(:after_collect)
|
25
|
+
if options[:render_value].nil?
|
26
|
+
options[:render_value] = lambda{|value| compact_values(value).join(' oder ') }
|
27
|
+
end
|
28
|
+
if options[:solr_query].nil?
|
29
|
+
options[:solr_query] = lambda do |value|
|
30
|
+
if value.is_a?(Array)
|
31
|
+
values = compact_values(value)
|
32
|
+
if values.empty?
|
33
|
+
''
|
34
|
+
else
|
35
|
+
q = values.map{|val| "#{@name}:#{val}"}.join(' OR ')
|
36
|
+
"(#{q})"
|
37
|
+
end
|
38
|
+
else
|
39
|
+
"#{@name}:#{value}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
super filter_name, options
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Generieren Select-Box für ein Sematic-Form
|
48
|
+
# Params: siehe MultiSolr::SolrFilterSimple#render_for_semantic_form
|
49
|
+
# returns: HTML-Code des Input-Feldes als Select-Box
|
50
|
+
def render_for_semantic_form sform, value, context=nil, form_input_options={}
|
51
|
+
form_input_options = @options[:semantic_form].merge form_input_options if @options.key? :semantic_form
|
52
|
+
set_label form_input_options
|
53
|
+
data = self.collection_data(nil, context)
|
54
|
+
html_options = form_input_options[:input_html]
|
55
|
+
if html_options
|
56
|
+
if html_options[:size]
|
57
|
+
# size wird als max-size verstanden. wenn akt. Data-Range kleiner
|
58
|
+
# ist, dann darauf reduzieren
|
59
|
+
html_options[:size] = [data.size+1, html_options[:size].to_i].min
|
60
|
+
end
|
61
|
+
end
|
62
|
+
form_input_options.merge! :collection => data
|
63
|
+
sform.input "filter_#{@name}", form_input_options
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Ermittelt den Wertebereich entweder über die bei den Options angegebene Proc
|
68
|
+
# oder über list_possible_values des Searchers (mit den Namen des Filters als Parameter)
|
69
|
+
# Params:
|
70
|
+
# core_handler: Instanz des konkreten Solr-CoreHandler (MultiSolr::SingleCoreHandler)
|
71
|
+
# context: Hash mit dem Such-Context.
|
72
|
+
# search_request: optional bestehendes SearchRequest (für DrillDown-Funktionalität)
|
73
|
+
# returns: Array mit dem Wertebereich
|
74
|
+
def collection_data core_handler, context, search_request=nil
|
75
|
+
if @collection_proc
|
76
|
+
data = @collection_proc.call(context)
|
77
|
+
else
|
78
|
+
data = core_handler.cached_list_possible_values(self.name, context, search_request)
|
79
|
+
end
|
80
|
+
if @after_collect_proc
|
81
|
+
data = @after_collect_proc.call(data)
|
82
|
+
data.compact!
|
83
|
+
end
|
84
|
+
data
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# Wandeltangegebener value in ein Array (wenn es noch keins ist)
|
89
|
+
# Bereinigt das Array von leeren Elementen
|
90
|
+
|
91
|
+
def compact_values value
|
92
|
+
value = [value] unless value.is_a?(Array)
|
93
|
+
value.delete_if(&:blank?)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Filter für Datumsbereiche mit von- und bis-Datum
|
2
|
+
|
3
|
+
class MultiSolr::SolrFilterDate < MultiSolr::SolrFilterSimple
|
4
|
+
|
5
|
+
|
6
|
+
# Constructor des Filters
|
7
|
+
# Params:
|
8
|
+
# filter_name: Name des Filters als Symbol
|
9
|
+
# options: optionale Hash mit Optionen (siehe SolrFilterSimple) plus:
|
10
|
+
# :mode Type der Nutzung des ang. Datums (Symbol):
|
11
|
+
# :from => Datum wird mit Zeit 00:00:00 genutzt
|
12
|
+
# :to => Datum wird mit Zeit 23:59:59 genutzt
|
13
|
+
# nil => Datum wird im Bereich 00:00:00 bis 23:59:59
|
14
|
+
#
|
15
|
+
def initialize filter_name, options={}
|
16
|
+
@mode = options.delete(:mode)
|
17
|
+
super(filter_name, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Erzeugen des SolR-Query-Strings
|
22
|
+
def build_solr_query value
|
23
|
+
return nil if value.blank?
|
24
|
+
date_range = nil
|
25
|
+
case @mode
|
26
|
+
when :from
|
27
|
+
date_range = "[#{value}T00:00:00Z TO *]"
|
28
|
+
when :to
|
29
|
+
date_range = "[* TO #{value}T23:59:59Z]"
|
30
|
+
else
|
31
|
+
date_range = "[#{value}T00:00:00Z TO #{value}T23:59:59Z]"
|
32
|
+
end
|
33
|
+
"#{@field_name}:#{date_range}"
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def render_value value
|
38
|
+
value.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Filter für Datumsbereiche mit von- und bis-Datum
|
2
|
+
|
3
|
+
class MultiSolr::SolrFilterDateRange < MultiSolr::SolrFilterSimple
|
4
|
+
|
5
|
+
# Erzeugen des SolR-Query-Strings
|
6
|
+
def build_solr_query value
|
7
|
+
from, to = extract_from_to_in_ISO8601 value
|
8
|
+
return nil if from.nil? && to.nil?
|
9
|
+
"#{@field_name}:[#{from || '*'} TO #{to || '*'}]"
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def render_value value
|
14
|
+
from, to = extract_from_to value
|
15
|
+
return '' if from.nil? && to.nil?
|
16
|
+
s = []
|
17
|
+
s << ">=#{from}" unless from.blank?
|
18
|
+
s << "<=#{to}" unless to.blank?
|
19
|
+
s.join(' und ')
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# Generieren der 2 Input-Felder mit der Option :as => :date_picker
|
24
|
+
# Dadurch können diesem Felder das jQuery-Datepicker-UI nutzen
|
25
|
+
# Params: siehe MultiSolr::SolrFilterSimple#render_for_semantic_form
|
26
|
+
# returns: HTML-Code mit 2 Input-Feldern
|
27
|
+
def render_for_semantic_form sform, value, context=nil, form_input_options={}
|
28
|
+
set_label form_input_options
|
29
|
+
label = form_input_options[:label]
|
30
|
+
form_input_options.merge! :as => :date_picker
|
31
|
+
from, to = extract_from_to value
|
32
|
+
date_range = Struct.new("#{@name}_from".to_sym, "#{@name}_to".to_sym).new from,to
|
33
|
+
sform.semantic_fields_for "filter_#{@name}", date_range do |filter_form|
|
34
|
+
form_input_options[:label] = "#{label} ab"
|
35
|
+
sform.template.concat filter_form.input("#{@name}_from", form_input_options)
|
36
|
+
form_input_options[:label] = "#{label} bis"
|
37
|
+
sform.template.concat filter_form.input("#{@name}_to", form_input_options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Aus dem 'value' von und bis extrahieren
|
43
|
+
# Params:
|
44
|
+
# value: Hash mit from- und to-Datumsangabe (mit Filternamen als Prefix)
|
45
|
+
# Beispiel: { 'create_date_from' => '2011-01-01', 'create_date_to' => '2011-06-01' }
|
46
|
+
# returns: Array mit von und bis ['2011-01-01', '2011-06-01']
|
47
|
+
def extract_from_to value
|
48
|
+
return nil if value.blank? || !value.is_a?(Hash) || value.empty?
|
49
|
+
[ value["#{@name}_from"], value["#{@name }_to"] ]
|
50
|
+
end
|
51
|
+
|
52
|
+
def extract_from_to_in_ISO8601 value
|
53
|
+
from, to = extract_from_to value
|
54
|
+
d_from = from.blank? ? nil : "#{from}T00:00:00Z"
|
55
|
+
d_to = to.blank? ? nil : "#{to}T23:59:59Z"
|
56
|
+
[d_from, d_to]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Einfacher Solr-Filter mit einem String als Value
|
2
|
+
# Ist auch Basisklasse für alle erweiterten Filter
|
3
|
+
|
4
|
+
class MultiSolr::SolrFilterSimple
|
5
|
+
|
6
|
+
attr_reader :name # Name des Filters als Symbol
|
7
|
+
attr_reader :options # Options des Filters
|
8
|
+
|
9
|
+
# Constructor des Filters
|
10
|
+
# Params:
|
11
|
+
# filter_name: Name des Filters als Symbol
|
12
|
+
# options: optionale Hash mit den folgenden Optionen (sind alle optional):
|
13
|
+
# :render_value Proc welcher den Filter-Value in einem String zur Darstellung generiert
|
14
|
+
# Ist dieser nicht angegeben so wird 'value.to_s' benutzt
|
15
|
+
# Beispiel: :render_value => lambda{|value| ItemSize::HANDLINGS[value.to_i] }
|
16
|
+
# :field_name Name des zu nutzenden Solr-Fields, default ist filter_name
|
17
|
+
# :solr_query Proc welcher den SolR-Query-String mit den Filter-Value bildet.
|
18
|
+
# Wenn nicht angegeben wird <field_name>:<value> benutzt
|
19
|
+
# Beispiel: :solr_query => lambda{|value| "teileanzahl:[#{value} TO *]" }
|
20
|
+
#
|
21
|
+
def initialize name, options={}
|
22
|
+
@name = name
|
23
|
+
@field_name = options[:field_name] || @name
|
24
|
+
@value_render_proc = options.delete(:render_value) || lambda{|value| value.to_s }
|
25
|
+
@solr_query_proc = options.delete(:solr_query) || lambda{|value| "#{@field_name}:#{value}"}
|
26
|
+
@options = options || {}
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Bilden des SolR-Query-Strings entweder
|
31
|
+
# per bei der Erzeugung angegebenen solr-query-Proc
|
32
|
+
# oder aus Filter-Namen und dem spezifizierten 'value'
|
33
|
+
# Besteht der 'value' aus mehren Worten, so wird er automatisch in Hochkomma eingeschlossen
|
34
|
+
# ( 'test sample' => '"test sample"')
|
35
|
+
# Params:
|
36
|
+
# value: der konkrete Wert für diesen Filter
|
37
|
+
# returns: String in SOLR-Query-Syntax
|
38
|
+
def build_solr_query value
|
39
|
+
return nil if value.blank?
|
40
|
+
# wenn Leerzeichen vorkommen dann String in " einschliessen
|
41
|
+
value = "\"#{value}\"" if value =~ /\s+/
|
42
|
+
@solr_query_proc.call(value)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Konvertieren der Wertes in den Darstellungs-String
|
47
|
+
# Nutzt wenn bei den Init-Options angegeben den hinterlegten Proc (value_render).
|
48
|
+
# Ansonsten wird nur 'value.to_s' aufgerufen.
|
49
|
+
# Params:
|
50
|
+
# value: der konkrete Wert für diesen Filter
|
51
|
+
# returns: String
|
52
|
+
def render_value value
|
53
|
+
return '' if value.nil?
|
54
|
+
@value_render_proc.call(value)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
# Konvertieren der Wertes in HTML-String für ein Semantic-Form
|
61
|
+
# Params:
|
62
|
+
# sform: das Semantic-Form-Object
|
63
|
+
# value: der konkrete Wert für diesen Filter
|
64
|
+
# context: optionaler Hash mit dem Such-Context z.B. mit;
|
65
|
+
# :solr_searcher_class => Classe des konkreten Searchers
|
66
|
+
# :force_query_params => Parameter für die SolR-Force-Query
|
67
|
+
# form_input_options: optionale Formula-Input-Feld-Options.
|
68
|
+
# Diese werden 1:1 an die Semantic-Form-Methode 'input' weitergegeben
|
69
|
+
#
|
70
|
+
# returns: HTML-Code des Input-Feldes
|
71
|
+
def render_for_semantic_form sform, value, context=nil, form_input_options={}
|
72
|
+
form_input_options = @options[:semantic_form].merge form_input_options if @options.key? :semantic_form
|
73
|
+
set_label form_input_options
|
74
|
+
sform.input "filter_#{@name}", form_input_options
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def label
|
79
|
+
I18n.t("solr_search.#{@name}", :default => @name.to_s)
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
# Setzt in die angegebebn 'form_input_options' das Label (nur wenn in diesen noch kein :label definiert ist).
|
85
|
+
# Dieses wird gebildet aus den Filter-Namen unter Nutzung von I18n mit den Prefiy 'solr_search.'.
|
86
|
+
# Beispiel:
|
87
|
+
# filter-name = :lkz => I18n.t('solr_search.lkz')
|
88
|
+
def set_label form_input_options
|
89
|
+
form_input_options.merge!(:label => self.label) unless form_input_options.key?(:label)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
class MultiSolr::TimelineCoreHandler
|
4
|
+
|
5
|
+
attr_reader :simple_core_handler_class
|
6
|
+
attr_reader :core_group_name
|
7
|
+
attr_reader :solr_url
|
8
|
+
|
9
|
+
|
10
|
+
def initialize solr_url, core_group_name, simple_core_handler_class
|
11
|
+
@simple_core_handler_class = simple_core_handler_class
|
12
|
+
@core_group_name = core_group_name
|
13
|
+
@solr_url = solr_url || raise("No solr-url given!")
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def create_single_core_handler core_name=nil, options=nil
|
18
|
+
core_name ||= last_core_name
|
19
|
+
@simple_core_handler_class.new @solr_url, core_name, options
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
# Liefert Array mit den Namen der verfügbaren Cores, die mit dem Core-Namen (see core_name) beginnen
|
25
|
+
# Diese Liste wird gecached
|
26
|
+
def list_cores include_empties=false
|
27
|
+
return @cores if @cores
|
28
|
+
status = self.core_status
|
29
|
+
@cores = []
|
30
|
+
matcher = Regexp.new "^#{@core_group_name}"
|
31
|
+
status.each do |core_name, data|
|
32
|
+
next unless matcher.match(core_name)
|
33
|
+
next if data['index']['numDocs'] < 3 && !include_empties
|
34
|
+
@cores << core_name
|
35
|
+
end
|
36
|
+
@cores.sort!
|
37
|
+
MultiSolr.logger.info "MultiSolr::TimelineCoreHandler.list_cores: #{@cores.join(',')}"
|
38
|
+
@cores
|
39
|
+
end
|
40
|
+
|
41
|
+
# Rücksetzen Cache der core-liste (see list_cores)
|
42
|
+
def reset_cores
|
43
|
+
@cores = @last_core_name = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Liefert Name des letzte Cores der laut alphabetischer Liste (see list_cores) existiert
|
47
|
+
def last_core_name
|
48
|
+
@last_core_name ||= list_cores.last
|
49
|
+
end
|
50
|
+
|
51
|
+
def base_connection
|
52
|
+
@_connection ||= RSolr.connect :url => @solr_url
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def core_connection core_name=nil
|
57
|
+
core_name ||= last_core_name
|
58
|
+
RSolr.connect :url => "#{@solr_url}/#{core_name}"
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def create_core suffix=nil
|
63
|
+
suffix = Time.now.strftime('%Y%m%d-%H%M') if suffix.nil?
|
64
|
+
new_core_name = "#{@core_group_name}-#{suffix}"
|
65
|
+
status = self.core_status last_core_name
|
66
|
+
old_name = status['name']
|
67
|
+
instance_dir_old = status['instanceDir']
|
68
|
+
instance_dir = instance_dir_old.sub(/^solr\//, '') # führendes solr im instanceDir ist zuviel, also entfernen
|
69
|
+
data_dir = status['dataDir'].sub(/#{old_name}\/$/, new_core_name)
|
70
|
+
data_dir.sub!(/^#{instance_dir_old}/, '')# führendes instanceDir im dataDir ist zuviel, also entfernen
|
71
|
+
res = self.base_connection.get 'admin/cores', :params => {:action => 'CREATE',
|
72
|
+
:name => new_core_name,
|
73
|
+
:instanceDir => instance_dir,
|
74
|
+
:dataDir => data_dir}
|
75
|
+
reset_cores
|
76
|
+
MultiSolr.logger.info "MultiSolr::TimelineCoreHandler.create_core: Core '#{new_core_name}' created. dataDir=#{data_dir}, instanceDir=#{instance_dir}"
|
77
|
+
new_core_name
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def dataimport import_handler_name, command='full-import', core_name=nil
|
82
|
+
core_name ||= last_core_name
|
83
|
+
con = core_connection core_name
|
84
|
+
res = con.get import_handler_name, :params => {:command => command}
|
85
|
+
MultiSolr.logger.info "MultiSolr::TimelineCoreHandler.dataimport: core=#{core_name}, command=#{command}, handler=#{import_handler_name}"
|
86
|
+
res
|
87
|
+
end
|
88
|
+
|
89
|
+
# Entfernen angegebenen Core aus der Core-Liste inkl. unload-Befehl an den Solr
|
90
|
+
# Achtung! Diese Methode löscht kann nur dann die physischen Daten des Cores löschen,
|
91
|
+
# wenn dieser mit einer absoluten Pfad-Angabe im solr konfiguriert ist!
|
92
|
+
# Parameter:
|
93
|
+
# core_name: Name des zu löschenden Cores
|
94
|
+
# with_data: optionaler Angabe ob Daten mit gelöscht werden sollen (Standardmäßig aus)
|
95
|
+
def remove_core core_name, with_data=false
|
96
|
+
status = self.core_status core_name
|
97
|
+
raise "no core '#{core_name}'!" if status.nil? || status['name'].nil?
|
98
|
+
base_connection.get 'admin/cores', :params => {:action => 'unload', :core => core_name}
|
99
|
+
MultiSolr.logger.info "MultiSolr::TimelineCoreHandler.remove_core: Core '#{core_name}' unloaded"
|
100
|
+
if with_data
|
101
|
+
data_dir = status['dataDir']
|
102
|
+
raise "No absolute DataDir-Path! Only Core was unloaded!" unless data_dir.start_with?('/')
|
103
|
+
FileUtils.rm_rf data_dir
|
104
|
+
end
|
105
|
+
reset_cores
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
# Liefert Core-Status evtl. aller Cores oder wenn Core-Name angegeben des einzelnen Cores
|
111
|
+
# returns Hash mit den Statusdaten
|
112
|
+
# Beispiel für alle Cores:
|
113
|
+
# {'core-01'=>{'name'=>'core-01',
|
114
|
+
# 'instanceDir'=>'solr/cobra-stock/',
|
115
|
+
# 'dataDir'=>'solr/cobra-stock/../../data/cobra-stock/',
|
116
|
+
# 'startTime'=>'2012-04-11T09:49:07.93Z',
|
117
|
+
# 'uptime'=>7796905,
|
118
|
+
# 'index'=>{'numDocs'=>1369046,'maxDoc'=>1369046,'version'=>1334134600492,'optimized'=>true,'current'=>true,'hasDeletions'=>false,'directory'=>'org.apache.lucene.store.NIOFSDirectory:org.apache.lucene.store.NIOFSDirectory@/home/bledig/Projects/lava/multi-solr/data/cobra-stock-20120411-1123/index lockFactory=org.apache.lucene.store.NativeFSLockFactory@1896a4c','lastModified'=>'2012-04-11T09:43:32Z'}},
|
119
|
+
# },...
|
120
|
+
# }
|
121
|
+
def core_status core_name=nil
|
122
|
+
params = {:action => 'STATUS' }
|
123
|
+
params[:core] = core_name if core_name
|
124
|
+
res = base_connection.get 'admin/cores', :params => params
|
125
|
+
status = res && res['status']
|
126
|
+
raise 'No status for cores available' if status.nil?
|
127
|
+
return status[core_name] if core_name
|
128
|
+
status
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
data/lib/multi_solr.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
require 'logger'
|
3
|
+
require 'active_support/cache'
|
4
|
+
|
5
|
+
require 'multi_solr/version'
|
6
|
+
require 'multi_solr/solr_filter_simple'
|
7
|
+
require 'multi_solr/solr_filter_collection'
|
8
|
+
require 'multi_solr/solr_filter_date'
|
9
|
+
require 'multi_solr/solr_filter_date_range'
|
10
|
+
require 'multi_solr/solr_filter_free_query'
|
11
|
+
require 'multi_solr/filter_value_composite'
|
12
|
+
require 'multi_solr/search_request'
|
13
|
+
require 'multi_solr/search_result'
|
14
|
+
require 'multi_solr/base_searcher'
|
15
|
+
require 'multi_solr/single_core_handler'
|
16
|
+
require 'multi_solr/timeline_core_handler'
|
17
|
+
|
18
|
+
module MultiSolr
|
19
|
+
|
20
|
+
@@logger = nil
|
21
|
+
@@cache = nil
|
22
|
+
|
23
|
+
def logger
|
24
|
+
return Rails.logger if defined? Rails
|
25
|
+
if @@logger.nil?
|
26
|
+
@@logger = Logger.new($stdout)
|
27
|
+
end
|
28
|
+
@@logger
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def cache
|
33
|
+
return Rails.cache if defined? Rails
|
34
|
+
if @@cache.nil?
|
35
|
+
@@cache = ActiveSupport::Cache::MemoryStore.new
|
36
|
+
end
|
37
|
+
@@cache
|
38
|
+
end
|
39
|
+
|
40
|
+
module_function :logger, :cache
|
41
|
+
|
42
|
+
end
|
43
|
+
|
data/multi-solr.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "multi_solr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "multi-solr"
|
7
|
+
s.version = MultiSolr::VERSION
|
8
|
+
s.authors = ["Bernd Ledig"]
|
9
|
+
s.email = ["bernd.ledig@ottogroup.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{SOLR-Framework with support for multiple SOLR-Cores}
|
12
|
+
s.description = %q{SOLR-Framework wit multi-core supoort and filters}
|
13
|
+
|
14
|
+
s.rubyforge_project = "multi-solr"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_runtime_dependency "rsolr", '>1.0', '<2.0'
|
23
|
+
s.add_runtime_dependency "activesupport", '>3.0', '<4.0'
|
24
|
+
s.add_runtime_dependency "i18n"
|
25
|
+
|
26
|
+
s.add_development_dependency "rake"
|
27
|
+
s.add_development_dependency "rspec", '>2.7', '<3.0'
|
28
|
+
end
|