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.
Files changed (53) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +1 -0
  5. data/lib/multi_solr/base_searcher.rb +393 -0
  6. data/lib/multi_solr/filter_value_composite.rb +33 -0
  7. data/lib/multi_solr/rails_form_render_helper.rb +84 -0
  8. data/lib/multi_solr/search_request.rb +209 -0
  9. data/lib/multi_solr/search_result.rb +127 -0
  10. data/lib/multi_solr/single_core_handler.rb +341 -0
  11. data/lib/multi_solr/solr_filter_collection.rb +97 -0
  12. data/lib/multi_solr/solr_filter_date.rb +46 -0
  13. data/lib/multi_solr/solr_filter_date_range.rb +62 -0
  14. data/lib/multi_solr/solr_filter_free_query.rb +11 -0
  15. data/lib/multi_solr/solr_filter_simple.rb +96 -0
  16. data/lib/multi_solr/timeline_core_handler.rb +131 -0
  17. data/lib/multi_solr/version.rb +3 -0
  18. data/lib/multi_solr.rb +43 -0
  19. data/multi-solr.gemspec +28 -0
  20. data/spec/fixtures/solr-testdata.yml +13 -0
  21. data/spec/multi_solr/base_searcher_spec.rb +212 -0
  22. data/spec/multi_solr/search_request_spec.rb +45 -0
  23. data/spec/multi_solr/search_result_spec.rb +113 -0
  24. data/spec/multi_solr/single_core_handler_spec.rb +169 -0
  25. data/spec/multi_solr/timeline_core_handler_spec.rb +107 -0
  26. data/spec/solr_test_helper.rb +15 -0
  27. data/spec/solr_testdata_provider.rb +89 -0
  28. data/spec/spec_helper.rb +27 -0
  29. data/test-solr/.gitignore +4 -0
  30. data/test-solr/articles.xml +6 -0
  31. data/test-solr/etc/jetty.xml +227 -0
  32. data/test-solr/etc/webdefault.xml +410 -0
  33. data/test-solr/lib/jetty-6.1.26-patched-JETTY-1340.jar +0 -0
  34. data/test-solr/lib/jetty-LICENSE.txt +202 -0
  35. data/test-solr/lib/jetty-NOTICE.txt +36 -0
  36. data/test-solr/lib/jetty-util-6.1.26-patched-JETTY-1340.jar +0 -0
  37. data/test-solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
  38. data/test-solr/lib/jsp-2.1/jsp-2.1-glassfish-2.1.v20091210.jar +0 -0
  39. data/test-solr/lib/jsp-2.1/jsp-2.1-jetty-6.1.26.jar +0 -0
  40. data/test-solr/lib/jsp-2.1/jsp-api-2.1-glassfish-2.1.v20091210.jar +0 -0
  41. data/test-solr/lib/lukeall-3.4.0_1.jar +0 -0
  42. data/test-solr/lib/servlet-api-2.5-20081211.jar +0 -0
  43. data/test-solr/solr/lib/apache-solr-dataimporthandler-3.4.0.jar +0 -0
  44. data/test-solr/solr/solr.xml +20 -0
  45. data/test-solr/solr/testcore/conf/dataimport-test.xml +12 -0
  46. data/test-solr/solr/testcore/conf/schema.xml +42 -0
  47. data/test-solr/solr/testcore/conf/solr_schema.css +58 -0
  48. data/test-solr/solr/testcore/conf/solr_schema.xsl +72 -0
  49. data/test-solr/solr/testcore/conf/solrconfig.xml +72 -0
  50. data/test-solr/start-test-solr.sh +10 -0
  51. data/test-solr/start.jar +0 -0
  52. data/test-solr/webapps/solr.war +0 -0
  53. 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 << "&gt;=#{from}" unless from.blank?
18
+ s << "&lt;=#{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,11 @@
1
+ # Filter für eine freie Query-Eingabe die direkt so an den SOLR geht
2
+
3
+ class MultiSolr::SolrFilterFreeQuery < MultiSolr::SolrFilterSimple
4
+
5
+ def build_solr_query value
6
+ return nil if value.blank?
7
+ value
8
+ end
9
+
10
+ end
11
+
@@ -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
@@ -0,0 +1,3 @@
1
+ module MultiSolr
2
+ VERSION = "01.01.05"
3
+ 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
+
@@ -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
@@ -0,0 +1,13 @@
1
+ ---
2
+ - id: 101
3
+ lager_id: 8
4
+ menge: 7
5
+ artikelnr: 124536
6
+ - id: 102
7
+ lager_id: 8
8
+ menge: 7
9
+ artikelnr: 847362
10
+ - id: 103
11
+ lager_id: 24
12
+ menge: 1
13
+ artikelnr: 895466