active_triples-solrizer 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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>