multi-solr 01.01.05
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 +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
|