active_triples-solrizer 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,52 @@
1
+ module ActiveTriples::Solrizer
2
+ class IndexingService
3
+ # include ::Solrizer::Common
4
+ attr_reader :object
5
+
6
+ def initialize(obj)
7
+ @object = obj
8
+ end
9
+
10
+ def self.profile_solr_name
11
+ # @profile_solr_name ||= ActiveFedora::SolrQueryBuilder.solr_name("object_profile", :displayable)
12
+ @profile_solr_name ||= :object_profile_ss
13
+ end
14
+
15
+ def profile_service
16
+ ProfileIndexingService
17
+ end
18
+
19
+ def properties_service
20
+ PropertiesIndexingService
21
+ end
22
+
23
+ # Creates a solr document hash for the {#object}
24
+ # @yield [Hash] yields the solr document
25
+ # @return [Hash] the solr document
26
+ def generate_solr_document
27
+ solr_doc = {}
28
+ # Solrizer.set_field(solr_doc, 'system_create', c_time, :stored_sortable)
29
+ # Solrizer.set_field(solr_doc, 'system_modified', m_time, :stored_sortable)
30
+ solr_doc.merge!(SOLR_DOCUMENT_ID.to_sym => object.id)
31
+ solr_doc.merge!(:at_model_ssi => object.class.to_s) # TODO dynamic for now, but probably should be static solr field
32
+ solr_doc.merge!(self.class.profile_solr_name => profile_service.new(object).export)
33
+ solr_doc.merge!(properties_service.new(object).export)
34
+ yield(solr_doc) if block_given?
35
+ solr_doc
36
+ end
37
+
38
+ # protected
39
+ #
40
+ # def c_time
41
+ # c_time = object.create_date.present? ? object.create_date : DateTime.now
42
+ # c_time = DateTime.parse(c_time) unless c_time.is_a?(DateTime)
43
+ # c_time
44
+ # end
45
+ #
46
+ # def m_time
47
+ # m_time = object.modified_date.present? ? object.modified_date : DateTime.now
48
+ # m_time = DateTime.parse(m_time) unless m_time.is_a?(DateTime)
49
+ # m_time
50
+ # end
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ require 'json'
2
+
3
+ module ActiveTriples::Solrizer
4
+ class ProfileIndexingService
5
+ def initialize(object=nil)
6
+ @object = object
7
+ end
8
+
9
+ def export
10
+ return '' if @object.nil?
11
+ # @object.serializable_hash.to_json
12
+ attributes(@object).to_json
13
+ end
14
+
15
+ def import( object_profile, object_class=nil )
16
+ raise ArgumentError, 'object_profile must not be nil' if
17
+ object_profile == nil
18
+
19
+ raise ArgumentError, 'object_class must not be nil if @object is nil' if
20
+ object_class == nil && @object == nil
21
+
22
+ raise ArgumentError, 'object_class must be same as class for @object' unless
23
+ object_class == nil || @object == nil || object_class == @object.class
24
+
25
+ # @object.deserializable_json(object_profile)
26
+
27
+ attrs = JSON(object_profile)
28
+ object_class ||= @object.class
29
+ @object = object_class.new(attrs['id'])
30
+ set_attributes(@object,attrs)
31
+ @object
32
+ end
33
+
34
+ private
35
+ def attributes(obj)
36
+ attrs = obj.attributes
37
+ attrs.each do |k,v|
38
+ next unless (v.is_a?(Array) || (Object::ActiveTriples.const_defined?("Relation") && v.is_a?(ActiveTriples::Relation)))
39
+ next unless v.first.is_a? ActiveTriples::Resource
40
+ attrs[k] = v.first.id
41
+ end
42
+ attrs
43
+ end
44
+
45
+ def set_attributes(obj,attrs)
46
+ attrs.each do |k,v|
47
+ next if k == 'id'
48
+ obj.set_value( k, v )
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,139 @@
1
+ module ActiveTriples::Solrizer
2
+ class PropertiesIndexingService
3
+
4
+ # supported types:
5
+ # :text - tokenized text
6
+ # :text_en - tokenized English text
7
+ # :string - non-tokenized string
8
+ # :integer
9
+ # :date - format for this date field is of the form 1995-12-31T23:59:59Z; Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z
10
+ # :long
11
+ # :double
12
+ # :float
13
+ # :boolean
14
+ # :coordinate - used to index the lat and long components for the "location"
15
+ # :location
16
+ # :guess - allow guessing of the type based on the type of the property value
17
+
18
+ # supported modifiers:
19
+ # :indexed - [all types except :coordinate] searchable, but not returned in solr doc unless also has :stored modifier
20
+ # :stored - [all types except :coordinate] returned in solr doc, but not searchable unless also has :indexed modifier
21
+ # :multiValued - [all types except :boolean, :coordinate] NOTE: if not specified and multiple values exist, only the first value is included in the solr doc
22
+ # :sortable - [all types except :boolean, :coordinate, :location] numbers are stored as trie version of numeric type; :string, :text, :text_XX have an extra alphaSort field
23
+ # :range - [all numeric types including :integer, :date, :long, :double, :float]; optimize for range queries
24
+ # :vectored - [valid for :text, :text_XX only]
25
+
26
+
27
+ def initialize(object)
28
+ @object = object
29
+ end
30
+
31
+ def export
32
+ solr_fields(@object)
33
+ end
34
+
35
+ def solr_fields(obj)
36
+ attrs_values = obj.attributes
37
+ solr_doc = {}
38
+ obj._active_triples_config.each do |key,cfg|
39
+ modifiers = parse_modifiers cfg.behaviors
40
+ next unless modifiers[:indexed] || modifiers[:stored]
41
+ values = attrs_values[key]
42
+ values = values.to_a if Object::ActiveTriples.const_defined?("Relation") && values.kind_of?(ActiveTriples::Relation)
43
+ next if values.nil? || !values.is_a?(Array) || values.first.nil?
44
+
45
+ encoded_data_type = encode_data_type( cfg.type, modifiers, values )
46
+ solr_fieldname = build_solr_fieldname( key, encoded_data_type, modifiers )
47
+ solr_value = build_solr_value( values, encoded_data_type, modifiers )
48
+ solr_doc[solr_fieldname.to_sym] = solr_value
49
+
50
+ next unless modifiers[:sortable] && [:t,:te,:s].include?( encoded_data_type )
51
+
52
+ solr_fieldname = "#{key}_ssort"
53
+ solr_doc[solr_fieldname.to_sym] = solr_value
54
+ end
55
+
56
+ solr_doc
57
+ end
58
+
59
+ private
60
+ def encode_data_type( data_type, modifiers, values )
61
+ return :t if data_type == :text
62
+ return :te if data_type == :text_en
63
+ return :s if data_type == :string
64
+ return :it if data_type == :integer && ( modifiers[:sortable] || modifiers[:range] )
65
+ return :i if data_type == :integer
66
+ return :dtt if data_type == :date && ( modifiers[:sortable] || modifiers[:range] )
67
+ return :dt if data_type == :date
68
+ return :lt if data_type == :long && ( modifiers[:sortable] || modifiers[:range] )
69
+ return :l if data_type == :long
70
+ return :dbt if data_type == :double && ( modifiers[:sortable] || modifiers[:range] )
71
+ return :db if data_type == :double
72
+ return :ft if data_type == :float && ( modifiers[:sortable] || modifiers[:range] )
73
+ return :f if data_type == :float
74
+ return :b if data_type == :boolean
75
+ return :coordinate if data_type == :coordinate
76
+ return :location if data_type == :location
77
+ return guess_data_type( modifiers, values ) if data_type == :guess
78
+ nil
79
+ end
80
+
81
+ def guess_data_type( modifiers, values )
82
+ data_type = :t # default to text which tokenizes a string
83
+ data_type = :i if values.first.is_a?( Fixnum )
84
+ data_type = :it if values.first.is_a?( Fixnum ) && ( modifiers[:sortable] || modifiers[:range] )
85
+ data_type = :l if values.first.is_a?( Bignum )
86
+ data_type = :lt if values.first.is_a?( Bignum ) && ( modifiers[:sortable] || modifiers[:range] )
87
+ data_type = :f if values.first.is_a?( Float )
88
+ data_type = :ft if values.first.is_a?( Float ) && ( modifiers[:sortable] || modifiers[:range] )
89
+ data_type = :b if values.first.is_a?( TrueClass ) || values.first.is_a?( FalseClass )
90
+ data_type = :dt if date? values.first
91
+ data_type
92
+ end
93
+
94
+ def parse_modifiers( cfg_behaviors )
95
+ modifiers = {}
96
+ return modifiers if cfg_behaviors.nil?
97
+ modifiers[:indexed] = cfg_behaviors.include?( :indexed ) ? true : false
98
+ modifiers[:stored] = cfg_behaviors.include?( :stored ) ? true : false
99
+ modifiers[:multiValued] = cfg_behaviors.include?( :multiValued ) ? true : false
100
+ modifiers[:sortable] = cfg_behaviors.include?( :sortable ) ? true : false
101
+ modifiers[:range] = cfg_behaviors.include?( :range ) ? true : false
102
+ modifiers[:vectored] = cfg_behaviors.include?( :vectored ) ? true : false
103
+ modifiers
104
+ end
105
+
106
+
107
+ def build_solr_fieldname( key, encoded_data_type, modifiers )
108
+ solr_fieldname = key + "_" + encoded_data_type.to_s
109
+ return solr_fieldname if encoded_data_type == :coordinate # no supported modifiers
110
+ solr_fieldname += "s" if modifiers[:stored]
111
+ solr_fieldname += "i" if modifiers[:indexed]
112
+ solr_fieldname += "m" if modifiers[:multiValued] && encoded_data_type != :b
113
+ solr_fieldname += "v" if modifiers[:vectored] && [:t,:te].include?( encoded_data_type )
114
+ solr_fieldname
115
+ end
116
+
117
+ def build_solr_value( values, encoded_data_type, modifiers )
118
+ if modifiers[:multiValued] && encoded_data_type != :b
119
+ solr_value = values.to_a
120
+ solr_value.collect! { |v| v.is_a?( ActiveTriples::Resource ) ? v.id : v }
121
+ else
122
+ # grab first value only and ignore the rest
123
+ solr_value = values.first
124
+ solr_value = solr_value.id if solr_value.is_a? ActiveTriples::Resource
125
+ end
126
+ solr_value
127
+ end
128
+
129
+ def date? test_date
130
+ return false unless test_date.is_a? String
131
+ begin
132
+ Date.parse(test_date)
133
+ rescue ArgumentError
134
+ return false
135
+ end
136
+ return true
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,141 @@
1
+ require 'rsolr'
2
+ require 'deprecation'
3
+
4
+ module ActiveTriples::Solrizer
5
+ class SolrService
6
+ extend Deprecation
7
+
8
+ attr_reader :conn
9
+
10
+ def initialize(host, args)
11
+ host = ActiveTriples::Solrizer.configuration.solr_uri unless host
12
+ args = {read_timeout: ActiveTriples::Solrizer.configuration.read_timeout,
13
+ open_timeout: ActiveTriples::Solrizer.configuration.open_timeout}.merge(args.dup)
14
+ args.merge!(url: host)
15
+ @conn = RSolr.connect args
16
+ end
17
+
18
+ class << self
19
+ def register(host=nil, args={})
20
+ Thread.current[:solr_service] = new(host, args)
21
+ end
22
+
23
+ def reset!
24
+ Thread.current[:solr_service] = nil
25
+ end
26
+
27
+ def instance
28
+ # Register Solr
29
+
30
+ unless Thread.current[:solr_service]
31
+ register(ActiveTriples::Solrizer.configuration.solr_uri)
32
+ end
33
+
34
+ raise SolrNotInitialized unless Thread.current[:solr_service]
35
+ Thread.current[:solr_service]
36
+ end
37
+
38
+ def lazy_reify_solr_results(solr_results, opts = {})
39
+ Deprecation.warn SolrService, "SolrService.lazy_reify_solr_results is deprecated. Use QueryResultBuilder.lazy_reify_solr_results instead. This will be removed in active-fedora 10.0"
40
+ QueryResultBuilder.lazy_reify_solr_results(solr_results, opts)
41
+ end
42
+
43
+ def reify_solr_results(solr_results, opts = {})
44
+ Deprecation.warn SolrService, "SolrService.reify_solr_results is deprecated. Use QueryResultBuilder.reify_solr_results instead. This will be removed in active-fedora 10.0"
45
+ QueryResultBuilder.reify_solr_results(solr_results, opts)
46
+ end
47
+
48
+ def reify_solr_result(hit, opts = {})
49
+ Deprecation.warn SolrService, "SolrService.reify_solr_result is deprecated. Use QueryResultBuilder.reify_solr_result instead. This will be removed in active-fedora 10.0"
50
+ QueryResultBuilder.reify_solr_result(hit, opts)
51
+ end
52
+
53
+ #Returns all possible classes for the solr object
54
+ def classes_from_solr_document(hit, opts = {})
55
+ Deprecation.warn SolrService, "SolrService.classes_from_solr_document is deprecated. Use QueryResultBuilder.classes_from_solr_document instead. This will be removed in active-fedora 10.0"
56
+ QueryResultBuilder.classes_from_solr_document(hit, opts)
57
+ end
58
+
59
+ #Returns the best singular class for the solr object
60
+ def class_from_solr_document(hit, opts = {})
61
+ Deprecation.warn SolrService, "SolrService.class_from_solr_document is deprecated. Use QueryResultBuilder.class_from_solr_document instead. This will be removed in active-fedora 10.0"
62
+ QueryResultBuilder.class_from_solr_document(hit, opts)
63
+ end
64
+
65
+ # Construct a solr query for a list of ids
66
+ # This is used to get a solr response based on the list of ids in an object's RELS-EXT relationhsips
67
+ # If the id_array is empty, defaults to a query of "id:NEVER_USE_THIS_ID", which will return an empty solr response
68
+ # @param [Array] id_array the ids that you want included in the query
69
+ def construct_query_for_ids(id_array)
70
+ Deprecation.warn SolrService, "SolrService.construct_query_for_ids is deprecated. Use SolrQueryBuilder.construct_query_for_ids instead. This will be removed in active-fedora 10.0"
71
+ SolrQueryBuilder.construct_query_for_ids(id_array)
72
+ end
73
+
74
+ def construct_query_for_pids(id_array)
75
+ Deprecation.warn SolrService, "construct_query_for_pids is deprecated and will be removed in active-fedora 10.0"
76
+ SolrQueryBuilder.construct_query_for_ids(id_array)
77
+ end
78
+
79
+ # Create a raw query clause suitable for sending to solr as an fq element
80
+ # @param [String] key
81
+ # @param [String] value
82
+ def raw_query(key, value)
83
+ Deprecation.warn SolrService, "SolrService.raw_query is deprecated. Use SolrQueryBuilder.raw_query instead. This will be removed in active-fedora 10.0"
84
+ SolrQueryBuilder.raw_query(key, value)
85
+ end
86
+
87
+ def solr_name(*args)
88
+ Deprecation.warn SolrService, "SolrService.solr_name is deprecated. Use SolrQueryBuilder.solr_name instead. This will be removed in active-fedora 10.0"
89
+ SolrQueryBuilder.solr_name(*args)
90
+ end
91
+
92
+ # Create a query with a clause for each key, value
93
+ # @param [Hash, Array<Array<String>>] field_pairs key is the predicate, value is the target_uri
94
+ # @param [String] join_with ('AND') the value we're joining the clauses with
95
+ # @example
96
+ # construct_query_for_rel [[:has_model, "info:fedora/afmodel:ComplexCollection"], [:has_model, "info:fedora/afmodel:ActiveFedora_Base"]], 'OR'
97
+ # # => _query_:"{!raw f=has_model_ssim}info:fedora/afmodel:ComplexCollection" OR _query_:"{!raw f=has_model_ssim}info:fedora/afmodel:ActiveFedora_Base"
98
+ #
99
+ # construct_query_for_rel [[Book.reflect_on_association(:library), "foo/bar/baz"]]
100
+ def construct_query_for_rel(field_pairs, join_with = 'AND')
101
+ Deprecation.warn SolrService, "SolrService.construct_query_for_rel is deprecated. Use SolrQueryBuilder.construct_query_for_rel instead. This will be removed in active-fedora 10.0"
102
+ SolrQueryBuilder.construct_query_for_rel(field_pairs, join_with)
103
+ end
104
+
105
+ def query(query, args={})
106
+ raw = args.delete(:raw)
107
+ args = args.merge(:q=>query, :qt=>'standard')
108
+ result = SolrService.instance.conn.get('select', :params=>args)
109
+ return result if raw
110
+ result['response']['docs']
111
+ end
112
+
113
+ def delete(id)
114
+ SolrService.instance.conn.delete_by_id(id, params: {'softCommit' => true})
115
+ end
116
+
117
+ # Get the count of records that match the query
118
+ # @param [String] query a solr query
119
+ # @param [Hash] args arguments to pass through to `args' param of SolrService.query (note that :rows will be overwritten to 0)
120
+ # @return [Integer] number of records matching
121
+ def count(query, args={})
122
+ args = args.merge(:raw=>true, :rows=>0)
123
+ SolrService.query(query, args)['response']['numFound'].to_i
124
+ end
125
+
126
+ # @param [Hash] doc the document to index
127
+ # @param [Hash] params
128
+ # :commit => commits immediately
129
+ # :softCommit => commit to memory, but don't flush to disk
130
+ def add(doc, params = {})
131
+ SolrService.instance.conn.add(doc, params: params)
132
+ end
133
+
134
+ def commit
135
+ SolrService.instance.conn.commit
136
+ end
137
+
138
+ end
139
+ end #SolrService
140
+ class SolrNotInitialized < StandardError;end
141
+ end #ActiveFedora
@@ -0,0 +1,5 @@
1
+ module ActiveTriples
2
+ module Solrizer
3
+ VERSION = "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,438 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <schema name="Hydra" version="1.5">
3
+ <!-- NOTE: various comments and unused configuration possibilities have been purged
4
+ from this file. Please refer to http://wiki.apache.org/solr/SchemaXml,
5
+ as well as the default schema file included with Solr -->
6
+
7
+ <uniqueKey>id</uniqueKey>
8
+
9
+ <fields>
10
+ <!-- If you remove this field, you must _also_ disable the update log in solrconfig.xml
11
+ or Solr won't start. _version_ and update log are required for SolrCloud
12
+ -->
13
+ <field name="_version_" type="long" indexed="true" stored="true"/>
14
+
15
+ <field name="id" type="string" stored="true" indexed="true" multiValued="false" required="true"/>
16
+ <field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
17
+
18
+ <field name="lat" type="tdouble" stored="true" indexed="true" multiValued="false"/>
19
+ <field name="lng" type="tdouble" stored="true" indexed="true" multiValued="false"/>
20
+
21
+ <!--these fields are hard coded in places in hydra-head -->
22
+ <field name="active_fedora_model_s" type="string" stored="true" indexed="true"/>
23
+ <field name="object_profile_display" type="string" stored="true" indexed="true"/>
24
+ <field name="has_model_s" type="string" stored="true" indexed="true"/>
25
+ <field name="is_governed_by_s" type="string" stored="true" indexed="true"/>
26
+
27
+ <!--
28
+ These are hard coded in places in hydra-head, but we hope to fix that.
29
+
30
+ <field name="inheritable_discover_access_person_t" type="string" stored="true" indexed="true" multiValued="true"/>
31
+ <field name="inheritable_read_access_person_t" type="string" stored="true" indexed="true" multiValued="true"/>
32
+ <field name="inheritable_edit_access_person_t" type="string" stored="true" indexed="true" multiValued="true"/>
33
+ <field name="inheritable_discover_access_group_t" type="string" stored="true" indexed="true" multiValued="true"/>
34
+ <field name="inheritable_read_access_group_t" type="string" stored="true" indexed="true" multiValued="true"/>
35
+ <field name="inheritable_edit_access_group_t" type="string" stored="true" indexed="true" multiValued="true"/>
36
+ <field name="read_access_person_t" type="string" stored="true" indexed="true" multiValued="true"/>
37
+ <field name="discover_access_person_t" type="string" stored="true" indexed="true" multiValued="true"/>
38
+ <field name="edit_access_person_t" type="string" stored="true" indexed="true" multiValued="true"/>
39
+ <field name="read_access_group_t" type="string" stored="true" indexed="true" multiValued="true"/>
40
+ <field name="edit_access_group_t" type="string" stored="true" indexed="true" multiValued="true"/>
41
+ <field name="discover_access_group_t" type="string" stored="true" indexed="true" multiValued="true"/>
42
+ -->
43
+
44
+
45
+ <!-- NOTE: not all possible Solr field types are represented in the dynamic fields -->
46
+
47
+ <!-- text (_t...) -->
48
+ <dynamicField name="*_ti" type="text" stored="false" indexed="true" multiValued="false"/>
49
+ <dynamicField name="*_tim" type="text" stored="false" indexed="true" multiValued="true"/>
50
+ <dynamicField name="*_ts" type="text" stored="true" indexed="false" multiValued="false"/>
51
+ <dynamicField name="*_tsm" type="text" stored="true" indexed="false" multiValued="true"/>
52
+ <dynamicField name="*_tsi" type="text" stored="true" indexed="true" multiValued="false"/>
53
+ <dynamicField name="*_tsim" type="text" stored="true" indexed="true" multiValued="true"/>
54
+ <dynamicField name="*_tiv" type="text" stored="false" indexed="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"/>
55
+ <dynamicField name="*_timv" type="text" stored="false" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
56
+ <dynamicField name="*_tsiv" type="text" stored="true" indexed="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"/>
57
+ <dynamicField name="*_tsimv" type="text" stored="true" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
58
+
59
+ <!-- English text (_te...) -->
60
+ <dynamicField name="*_tei" type="text_en" stored="false" indexed="true" multiValued="false"/>
61
+ <dynamicField name="*_teim" type="text_en" stored="false" indexed="true" multiValued="true"/>
62
+ <dynamicField name="*_tes" type="text_en" stored="true" indexed="false" multiValued="false"/>
63
+ <dynamicField name="*_tesm" type="text_en" stored="true" indexed="false" multiValued="true"/>
64
+ <dynamicField name="*_tesi" type="text_en" stored="true" indexed="true" multiValued="false"/>
65
+ <dynamicField name="*_tesim" type="text_en" stored="true" indexed="true" multiValued="true"/>
66
+ <dynamicField name="*_teiv" type="text_en" stored="false" indexed="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"/>
67
+ <dynamicField name="*_teimv" type="text_en" stored="false" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
68
+ <dynamicField name="*_tesiv" type="text_en" stored="true" indexed="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"/>
69
+ <dynamicField name="*_tesimv" type="text_en" stored="true" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
70
+
71
+ <!-- string (_s...) -->
72
+ <dynamicField name="*_si" type="string" stored="false" indexed="true" multiValued="false"/>
73
+ <dynamicField name="*_sim" type="string" stored="false" indexed="true" multiValued="true"/>
74
+ <dynamicField name="*_ss" type="string" stored="true" indexed="false" multiValued="false"/>
75
+ <dynamicField name="*_ssm" type="string" stored="true" indexed="false" multiValued="true"/>
76
+ <dynamicField name="*_ssi" type="string" stored="true" indexed="true" multiValued="false"/>
77
+ <dynamicField name="*_ssim" type="string" stored="true" indexed="true" multiValued="true"/>
78
+ <dynamicField name="*_ssort" type="alphaSort" stored="false" indexed="true" multiValued="false"/>
79
+
80
+ <!-- integer (_i...) -->
81
+ <dynamicField name="*_ii" type="int" stored="false" indexed="true" multiValued="false"/>
82
+ <dynamicField name="*_iim" type="int" stored="false" indexed="true" multiValued="true"/>
83
+ <dynamicField name="*_is" type="int" stored="true" indexed="false" multiValued="false"/>
84
+ <dynamicField name="*_ism" type="int" stored="true" indexed="false" multiValued="true"/>
85
+ <dynamicField name="*_isi" type="int" stored="true" indexed="true" multiValued="false"/>
86
+ <dynamicField name="*_isim" type="int" stored="true" indexed="true" multiValued="true"/>
87
+
88
+ <!-- trie integer (_it...) (for faster range queries) -->
89
+ <dynamicField name="*_iti" type="tint" stored="false" indexed="true" multiValued="false"/>
90
+ <dynamicField name="*_itim" type="tint" stored="false" indexed="true" multiValued="true"/>
91
+ <dynamicField name="*_its" type="tint" stored="true" indexed="false" multiValued="false"/>
92
+ <dynamicField name="*_itsm" type="tint" stored="true" indexed="false" multiValued="true"/>
93
+ <dynamicField name="*_itsi" type="tint" stored="true" indexed="true" multiValued="false"/>
94
+ <dynamicField name="*_itsim" type="tint" stored="true" indexed="true" multiValued="true"/>
95
+
96
+ <!-- date (_dt...) -->
97
+ <!-- The format for this date field is of the form 1995-12-31T23:59:59Z
98
+ Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z -->
99
+ <dynamicField name="*_dti" type="date" stored="false" indexed="true" multiValued="false"/>
100
+ <dynamicField name="*_dtim" type="date" stored="false" indexed="true" multiValued="true"/>
101
+ <dynamicField name="*_dts" type="date" stored="true" indexed="false" multiValued="false"/>
102
+ <dynamicField name="*_dtsm" type="date" stored="true" indexed="false" multiValued="true"/>
103
+ <dynamicField name="*_dtsi" type="date" stored="true" indexed="true" multiValued="false"/>
104
+ <dynamicField name="*_dtsim" type="date" stored="true" indexed="true" multiValued="true"/>
105
+
106
+ <!-- trie date (_dtt...) (for faster range queries) -->
107
+ <dynamicField name="*_dtti" type="tdate" stored="false" indexed="true" multiValued="false"/>
108
+ <dynamicField name="*_dttim" type="tdate" stored="false" indexed="true" multiValued="true"/>
109
+ <dynamicField name="*_dtts" type="tdate" stored="true" indexed="false" multiValued="false"/>
110
+ <dynamicField name="*_dttsm" type="tdate" stored="true" indexed="false" multiValued="true"/>
111
+ <dynamicField name="*_dttsi" type="tdate" stored="true" indexed="true" multiValued="false"/>
112
+ <dynamicField name="*_dttsim" type="tdate" stored="true" indexed="true" multiValued="true"/>
113
+
114
+ <!-- long (_l...) -->
115
+ <dynamicField name="*_li" type="long" stored="false" indexed="true" multiValued="false"/>
116
+ <dynamicField name="*_lim" type="long" stored="false" indexed="true" multiValued="true"/>
117
+ <dynamicField name="*_ls" type="long" stored="true" indexed="false" multiValued="false"/>
118
+ <dynamicField name="*_lsm" type="long" stored="true" indexed="false" multiValued="true"/>
119
+ <dynamicField name="*_lsi" type="long" stored="true" indexed="true" multiValued="false"/>
120
+ <dynamicField name="*_lsim" type="long" stored="true" indexed="true" multiValued="true"/>
121
+
122
+ <!-- trie long (_lt...) (for faster range queries) -->
123
+ <dynamicField name="*_lti" type="tlong" stored="false" indexed="true" multiValued="false"/>
124
+ <dynamicField name="*_ltim" type="tlong" stored="false" indexed="true" multiValued="true"/>
125
+ <dynamicField name="*_lts" type="tlong" stored="true" indexed="false" multiValued="false"/>
126
+ <dynamicField name="*_ltsm" type="tlong" stored="true" indexed="false" multiValued="true"/>
127
+ <dynamicField name="*_ltsi" type="tlong" stored="true" indexed="true" multiValued="false"/>
128
+ <dynamicField name="*_ltsim" type="tlong" stored="true" indexed="true" multiValued="true"/>
129
+
130
+ <!-- double (_db...) -->
131
+ <dynamicField name="*_dbi" type="double" stored="false" indexed="true" multiValued="false"/>
132
+ <dynamicField name="*_dbim" type="double" stored="false" indexed="true" multiValued="true"/>
133
+ <dynamicField name="*_dbs" type="double" stored="true" indexed="false" multiValued="false"/>
134
+ <dynamicField name="*_dbsm" type="double" stored="true" indexed="false" multiValued="true"/>
135
+ <dynamicField name="*_dbsi" type="double" stored="true" indexed="true" multiValued="false"/>
136
+ <dynamicField name="*_dbsim" type="double" stored="true" indexed="true" multiValued="true"/>
137
+
138
+ <!-- trie double (_dbt...) (for faster range queries) -->
139
+ <dynamicField name="*_dbti" type="tdouble" stored="false" indexed="true" multiValued="false"/>
140
+ <dynamicField name="*_dbtim" type="tdouble" stored="false" indexed="true" multiValued="true"/>
141
+ <dynamicField name="*_dbts" type="tdouble" stored="true" indexed="false" multiValued="false"/>
142
+ <dynamicField name="*_dbtsm" type="tdouble" stored="true" indexed="false" multiValued="true"/>
143
+ <dynamicField name="*_dbtsi" type="tdouble" stored="true" indexed="true" multiValued="false"/>
144
+ <dynamicField name="*_dbtsim" type="tdouble" stored="true" indexed="true" multiValued="true"/>
145
+
146
+ <!-- float (_f...) -->
147
+ <dynamicField name="*_fi" type="float" stored="false" indexed="true" multiValued="false"/>
148
+ <dynamicField name="*_fim" type="float" stored="false" indexed="true" multiValued="true"/>
149
+ <dynamicField name="*_fs" type="float" stored="true" indexed="false" multiValued="false"/>
150
+ <dynamicField name="*_fsm" type="float" stored="true" indexed="false" multiValued="true"/>
151
+ <dynamicField name="*_fsi" type="float" stored="true" indexed="true" multiValued="false"/>
152
+ <dynamicField name="*_fsim" type="float" stored="true" indexed="true" multiValued="true"/>
153
+
154
+ <!-- trie float (_ft...) (for faster range queries) -->
155
+ <dynamicField name="*_fti" type="tfloat" stored="false" indexed="true" multiValued="false"/>
156
+ <dynamicField name="*_ftim" type="tfloat" stored="false" indexed="true" multiValued="true"/>
157
+ <dynamicField name="*_fts" type="tfloat" stored="true" indexed="false" multiValued="false"/>
158
+ <dynamicField name="*_ftsm" type="tfloat" stored="true" indexed="false" multiValued="true"/>
159
+ <dynamicField name="*_ftsi" type="tfloat" stored="true" indexed="true" multiValued="false"/>
160
+ <dynamicField name="*_ftsim" type="tfloat" stored="true" indexed="true" multiValued="true"/>
161
+
162
+ <!-- boolean (_b...) -->
163
+ <dynamicField name="*_bi" type="boolean" stored="false" indexed="true" multiValued="false"/>
164
+ <dynamicField name="*_bs" type="boolean" stored="true" indexed="false" multiValued="false"/>
165
+ <dynamicField name="*_bsi" type="boolean" stored="true" indexed="true" multiValued="false"/>
166
+
167
+ <!-- Type used to index the lat and lon components for the "location" FieldType -->
168
+ <dynamicField name="*_coordinate" type="tdouble" indexed="true" stored="false" />
169
+
170
+ <!-- location (_ll...) -->
171
+ <dynamicField name="*_lli" type="location" stored="false" indexed="true" multiValued="false"/>
172
+ <dynamicField name="*_llim" type="location" stored="false" indexed="true" multiValued="true"/>
173
+ <dynamicField name="*_lls" type="location" stored="true" indexed="false" multiValued="false"/>
174
+ <dynamicField name="*_llsm" type="location" stored="true" indexed="false" multiValued="true"/>
175
+ <dynamicField name="*_llsi" type="location" stored="true" indexed="true" multiValued="false"/>
176
+ <dynamicField name="*_llsim" type="location" stored="true" indexed="true" multiValued="true"/>
177
+
178
+ <!-- you must define copyField source and dest fields explicity or schemaBrowser doesn't work -->
179
+ <field name="all_text_timv" type="text" stored="false" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
180
+
181
+ <!-- deprecated fields from pre-Solr 4.0 pre-hydra 5.0 -->
182
+ <!--
183
+ <field name="marc_display" type="string" indexed="false" stored="true" multiValued="false"/>
184
+ <field name="title_display" type="string" indexed="false" stored="true" multiValued="false"/>
185
+ <field name="title_vern_display" type="string" indexed="false" stored="true" multiValued="false"/>
186
+ <field name="subtitle_display" type="string" indexed="false" stored="true" multiValued="false"/>
187
+ <field name="subtitle_vern_display" type="string" indexed="false" stored="true" multiValued="false"/>
188
+ <field name="author_display" type="string" indexed="false" stored="true" multiValued="false"/>
189
+ <field name="author_vern_display" type="string" indexed="false" stored="true" multiValued="false"/>
190
+ -->
191
+ <!-- these fields are also used for display, so they must be stored -->
192
+ <!--
193
+ <field name="isbn_t" type="text" indexed="true" stored="true" multiValued="true"/>
194
+ <field name="language_facet" type="string" indexed="true" stored="true" multiValued="true" />
195
+ <field name="subject_topic_facet" type="string" indexed="true" stored="true" multiValued="true" />
196
+ <field name="subject_era_facet" type="string" indexed="true" stored="true" multiValued="true" />
197
+ <field name="subject_geo_facet" type="string" indexed="true" stored="true" multiValued="true" />
198
+ -->
199
+ <!-- pub_date is used for facet and display so it must be indexed and stored -->
200
+ <!--
201
+ <field name="pub_date" type="string" indexed="true" stored="true" multiValued="true"/>
202
+ -->
203
+ <!-- pub_date sort uses new trie-based int fields, which are recommended for any int and are displayable, sortable, and range-quer
204
+ we use 'tint' for faster range-queries. -->
205
+ <!--
206
+ <field name="pub_date_sort" type="tint" indexed="true" stored="true" multiValued="false"/>
207
+ -->
208
+ <!-- format is used for facet, display, and choosing which partial to use for the show view, so it must be stored and indexed -->
209
+ <!--
210
+ <field name="format" type="string" indexed="true" stored="true"/>
211
+
212
+ <dynamicField name="*_i" type="int" indexed="true" stored="true"/>
213
+ <dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true"/>
214
+ <dynamicField name="*_l" type="long" indexed="true" stored="true"/>
215
+ <dynamicField name="*_t" type="text" indexed="true" stored="true" multiValued="true"/>
216
+ <dynamicField name="*_txt" type="text_general" indexed="true" stored="true" multiValued="true"/>
217
+ <dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
218
+ <dynamicField name="*_f" type="float" indexed="true" stored="true"/>
219
+ <dynamicField name="*_d" type="double" indexed="true" stored="true"/>
220
+
221
+ <dynamicField name="ignored_*" type="ignored" multiValued="true"/>
222
+ <dynamicField name="attr_*" type="text_general" indexed="true" stored="true" multiValued="true"/>
223
+
224
+ <dynamicField name="random_*" type="random" />
225
+
226
+ <dynamicField name="*_display" type="string" indexed="false" stored="true" multiValued="true" />
227
+ <dynamicField name="*_facet" type="string" indexed="true" stored="true" multiValued="true" />
228
+ <dynamicField name="*_sort" type="string" indexed="true" stored="false" multiValued="false" />
229
+ <dynamicField name="*_unstem_search" type="text_general" indexed="true" stored="false" multiValued="true" />
230
+ <dynamicField name="*spell" type="textSpell" indexed="true" stored="false" multiValued="true" />
231
+ -->
232
+ <!-- uncomment the following to ignore any fields that don't already match an existing
233
+ field name or dynamic field, rather than reporting them as an error.
234
+ alternately, change the type="ignored" to some other type e.g. "text" if you want
235
+ unknown fields indexed and/or stored by default -->
236
+ <!--dynamicField name="*" type="ignored" multiValued="true" /-->
237
+
238
+ <!-- END hydra deprecated items -->
239
+
240
+ </fields>
241
+
242
+ <!-- START hydra deprecated items -->
243
+ <!--
244
+ <defaultSearchField>text</defaultSearchField>
245
+ -->
246
+ <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
247
+ <!--
248
+ <solrQueryParser defaultOperator="AND"/>
249
+
250
+ <copyField source="title_t" dest="title_unstem_search"/>
251
+ <copyField source="subtitle_t" dest="subtitle_unstem_search"/>
252
+ <copyField source="title_addl_t" dest="title_addl_unstem_search"/>
253
+ <copyField source="title_added_entry_t" dest="title_added_entry_unstem_search"/>
254
+ <copyField source="title_series_t" dest="title_series_unstem_search"/>
255
+ <copyField source="author_t" dest="author_unstem_search"/>
256
+ <copyField source="author_addl_t" dest="author_addl_unstem_search"/>
257
+ <copyField source="subject_t" dest="subject_unstem_search"/>
258
+ <copyField source="subject_addl_t" dest="subject_addl_unstem_search"/>
259
+ <copyField source="subject_topic_facet" dest="subject_topic_unstem_search"/>
260
+ -->
261
+ <!-- sort fields -->
262
+ <!--
263
+ <copyField source="pub_date" dest="pub_date_sort"/>
264
+ -->
265
+
266
+ <!-- spellcheck fields -->
267
+ <!-- default spell check; should match fields for default request handler -->
268
+ <!-- it won't work with a copy of a copy field -->
269
+ <!--
270
+ <copyField source="*_t" dest="spell"/>
271
+ <copyField source="*_facet" dest="spell"/>
272
+ -->
273
+ <!-- title spell check; should match fields for title request handler -->
274
+ <!--
275
+ <copyField source="title_t" dest="title_spell"/>
276
+ <copyField source="subtitle_t" dest="title_spell"/>
277
+ <copyField source="addl_titles_t" dest="title_spell"/>
278
+ <copyField source="title_added_entry_t" dest="title_spell"/>
279
+ <copyField source="title_series_t" dest="title_spell"/>
280
+ -->
281
+ <!-- author spell check; should match fields for author request handler -->
282
+ <!--
283
+ <copyField source="author_t" dest="author_spell"/>
284
+ <copyField source="author_addl_t" dest="author_spell"/>
285
+ -->
286
+ <!-- subject spell check; should match fields for subject request handler -->
287
+ <!--
288
+ <copyField source="subject_topic_facet" dest="subject_spell"/>
289
+ <copyField source="subject_t" dest="subject_spell"/>
290
+ <copyField source="subject_addl_t" dest="subject_spell"/>
291
+ -->
292
+
293
+ <!-- OpenSearch query field should match request handler search fields -->
294
+ <!--
295
+ <copyField source="title_t" dest="opensearch_display"/>
296
+ <copyField source="subtitle_t" dest="opensearch_display"/>
297
+ <copyField source="addl_titles_t" dest="opensearch_display"/>
298
+ <copyField source="title_added_entry_t" dest="opensearch_display"/>
299
+ <copyField source="title_series_t" dest="opensearch_display"/>
300
+ <copyField source="author_t" dest="opensearch_display"/>
301
+ <copyField source="author_addl_t" dest="opensearch_display"/>
302
+ <copyField source="subject_topic_facet" dest="opensearch_display"/>
303
+ <copyField source="subject_t" dest="opensearch_display"/>
304
+ <copyField source="subject_addl_t" dest="opensearch_display"/>
305
+ -->
306
+
307
+ <!-- Above, multiple source fields are copied to the [text] field.
308
+ Another way to map multiple source fields to the same
309
+ destination field is to use the dynamic field syntax.
310
+ copyField also supports a maxChars to copy setting. -->
311
+
312
+ <!-- <copyField source="*_t" dest="text" maxChars="3000"/> -->
313
+ <!--
314
+ <copyField source="*_s" dest="text"/>
315
+ <copyField source="*_t" dest="text"/>
316
+ <copyField source="*_facet" dest="text"/>
317
+ -->
318
+ <!-- copy name to alphaNameSort, a field designed for sorting by name -->
319
+ <!-- <copyField source="name" dest="alphaNameSort"/> -->
320
+
321
+ <!-- END hydra deprecated items -->
322
+
323
+ <!-- copy fields; note that you must define copyField source and dest fields explicity or schemaBrowser doesn't work -->
324
+ <!--
325
+ <copyField source="some_field" dest="all_text_timv" />
326
+ -->
327
+
328
+ <types>
329
+ <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
330
+ <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
331
+ <fieldType name="rand" class="solr.RandomSortField" omitNorms="true"/>
332
+
333
+ <!-- Default numeric field types. -->
334
+ <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
335
+ <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>
336
+ <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
337
+ <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>
338
+
339
+ <!-- trie numeric field types for faster range queries -->
340
+ <fieldType name="tint" class="solr.TrieIntField" precisionStep="8" positionIncrementGap="0"/>
341
+ <fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" positionIncrementGap="0"/>
342
+ <fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" positionIncrementGap="0"/>
343
+ <fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" positionIncrementGap="0"/>
344
+
345
+ <!-- The format for this date field is of the form 1995-12-31T23:59:59Z
346
+ Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z
347
+ -->
348
+ <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
349
+ <!-- A Trie based date field for faster date range queries and date faceting. -->
350
+ <fieldType name="tdate" class="solr.TrieDateField" precisionStep="6" positionIncrementGap="0"/>
351
+
352
+
353
+ <!-- This point type indexes the coordinates as separate fields (subFields)
354
+ If subFieldType is defined, it references a type, and a dynamic field
355
+ definition is created matching *___<typename>. Alternately, if
356
+ subFieldSuffix is defined, that is used to create the subFields.
357
+ Example: if subFieldType="double", then the coordinates would be
358
+ indexed in fields myloc_0___double,myloc_1___double.
359
+ Example: if subFieldSuffix="_d" then the coordinates would be indexed
360
+ in fields myloc_0_d,myloc_1_d
361
+ The subFields are an implementation detail of the fieldType, and end
362
+ users normally should not need to know about them.
363
+ -->
364
+ <fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
365
+
366
+ <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
367
+ <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
368
+
369
+ <!-- An alternative geospatial field type new to Solr 4. It supports multiValued and polygon shapes.
370
+ For more information about this and other Spatial fields new to Solr 4, see:
371
+ http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4
372
+ -->
373
+ <fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
374
+ geo="true" distErrPct="0.025" maxDistErr="0.000009" units="degrees" />
375
+
376
+ <fieldType name="text" class="solr.TextField" omitNorms="false">
377
+ <analyzer>
378
+ <tokenizer class="solr.ICUTokenizerFactory"/>
379
+ <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
380
+ <filter class="solr.TrimFilterFactory"/>
381
+ </analyzer>
382
+ </fieldType>
383
+
384
+ <!-- A text field that only splits on whitespace for exact matching of words -->
385
+ <fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100">
386
+ <analyzer>
387
+ <tokenizer class="solr.WhitespaceTokenizerFactory"/>
388
+ <filter class="solr.TrimFilterFactory"/>
389
+ </analyzer>
390
+ </fieldType>
391
+
392
+ <!-- single token analyzed text, for sorting. Punctuation is significant. -->
393
+ <fieldtype name="alphaSort" class="solr.TextField" sortMissingLast="true" omitNorms="true">
394
+ <analyzer>
395
+ <tokenizer class="solr.KeywordTokenizerFactory" />
396
+ <filter class="solr.ICUFoldingFilterFactory"/>
397
+ <filter class="solr.TrimFilterFactory" />
398
+ </analyzer>
399
+ </fieldtype>
400
+
401
+ <!-- A text field with defaults appropriate for English -->
402
+ <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
403
+ <analyzer>
404
+ <tokenizer class="solr.ICUTokenizerFactory"/>
405
+ <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
406
+ <filter class="solr.EnglishPossessiveFilterFactory"/>
407
+ <!-- EnglishMinimalStemFilterFactory is less aggressive than PorterStemFilterFactory: -->
408
+ <filter class="solr.EnglishMinimalStemFilterFactory"/>
409
+ <!--
410
+ <filter class="solr.PorterStemFilterFactory"/>
411
+ -->
412
+ <filter class="solr.TrimFilterFactory"/>
413
+ </analyzer>
414
+ </fieldType>
415
+
416
+ <!-- queries for paths match documents at that path, or in descendent paths -->
417
+ <fieldType name="descendent_path" class="solr.TextField">
418
+ <analyzer type="index">
419
+ <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
420
+ </analyzer>
421
+ <analyzer type="query">
422
+ <tokenizer class="solr.KeywordTokenizerFactory" />
423
+ </analyzer>
424
+ </fieldType>
425
+
426
+ <!-- queries for paths match documents at that path, or in ancestor paths -->
427
+ <fieldType name="ancestor_path" class="solr.TextField">
428
+ <analyzer type="index">
429
+ <tokenizer class="solr.KeywordTokenizerFactory" />
430
+ </analyzer>
431
+ <analyzer type="query">
432
+ <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
433
+ </analyzer>
434
+ </fieldType>
435
+
436
+ </types>
437
+
438
+ </schema>