qa 1.0.0 → 1.1.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +284 -2
  3. data/app/controllers/qa/linked_data_terms_controller.rb +127 -0
  4. data/config/authorities/linked_data/agrovoc.json +61 -0
  5. data/config/authorities/linked_data/loc.json +46 -0
  6. data/config/authorities/linked_data/oclc_fast.json +78 -0
  7. data/config/initializers/linked_data_authorities.rb +17 -0
  8. data/config/routes.rb +3 -0
  9. data/lib/qa.rb +15 -0
  10. data/lib/qa/authorities.rb +2 -0
  11. data/lib/qa/authorities/base.rb +1 -1
  12. data/lib/qa/authorities/crossref.rb +16 -0
  13. data/lib/qa/authorities/crossref/generic_authority.rb +63 -0
  14. data/lib/qa/authorities/geonames.rb +2 -1
  15. data/lib/qa/authorities/linked_data.rb +10 -0
  16. data/lib/qa/authorities/linked_data/config.rb +80 -0
  17. data/lib/qa/authorities/linked_data/config/search_config.rb +170 -0
  18. data/lib/qa/authorities/linked_data/config/term_config.rb +186 -0
  19. data/lib/qa/authorities/linked_data/find_term.rb +148 -0
  20. data/lib/qa/authorities/linked_data/generic_authority.rb +49 -0
  21. data/lib/qa/authorities/linked_data/rdf_helper.rb +102 -0
  22. data/lib/qa/authorities/linked_data/search_query.rb +143 -0
  23. data/lib/qa/version.rb +1 -1
  24. data/spec/controllers/linked_data_terms_controller_spec.rb +202 -0
  25. data/spec/fixtures/authorities/linked_data/lod_full_config.json +111 -0
  26. data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +54 -0
  27. data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +54 -0
  28. data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +52 -0
  29. data/spec/fixtures/authorities/linked_data/lod_lang_param.json +66 -0
  30. data/spec/fixtures/authorities/linked_data/lod_min_config.json +49 -0
  31. data/spec/fixtures/authorities/linked_data/lod_search_only_config.json +55 -0
  32. data/spec/fixtures/authorities/linked_data/lod_sort.json +27 -0
  33. data/spec/fixtures/authorities/linked_data/lod_term_only_config.json +59 -0
  34. data/spec/fixtures/funders-find-response.json +1 -0
  35. data/spec/fixtures/funders-noquery.json +1 -0
  36. data/spec/fixtures/funders-noresults.json +1 -0
  37. data/spec/fixtures/funders-result.json +1 -0
  38. data/spec/fixtures/journals-find-response-two-issn.json +1 -0
  39. data/spec/fixtures/journals-find-response.json +1 -0
  40. data/spec/fixtures/journals-noquery.json +1 -0
  41. data/spec/fixtures/journals-noresults.json +1 -0
  42. data/spec/fixtures/journals-result.json +705 -0
  43. data/spec/fixtures/lod_agrovoc_query_many_results.json +1 -0
  44. data/spec/fixtures/lod_agrovoc_query_no_results.json +1 -0
  45. data/spec/fixtures/lod_agrovoc_term_found.rdf.xml +217 -0
  46. data/spec/fixtures/lod_lang_search_en.rdf.xml +42 -0
  47. data/spec/fixtures/lod_lang_search_enfr.rdf.xml +48 -0
  48. data/spec/fixtures/lod_lang_search_enfrde.rdf.xml +54 -0
  49. data/spec/fixtures/lod_lang_search_fr.rdf.xml +42 -0
  50. data/spec/fixtures/lod_lang_term_en.rdf.xml +65 -0
  51. data/spec/fixtures/lod_lang_term_enfr.rdf.xml +71 -0
  52. data/spec/fixtures/lod_lang_term_enfr_noalt.rdf.xml +69 -0
  53. data/spec/fixtures/lod_lang_term_enfrde.rdf.xml +79 -0
  54. data/spec/fixtures/lod_lang_term_fr.rdf.xml +65 -0
  55. data/spec/fixtures/lod_loc_term_found.rdf.xml +262 -0
  56. data/spec/fixtures/lod_oclc_all_query_3_results.rdf.xml +142 -0
  57. data/spec/fixtures/lod_oclc_personalName_query_3_results.rdf.xml +128 -0
  58. data/spec/fixtures/lod_oclc_query_no_results.rdf.xml +13 -0
  59. data/spec/fixtures/lod_oclc_term_found.rdf.xml +51 -0
  60. data/spec/lib/authorities/crossref_spec.rb +180 -0
  61. data/spec/lib/authorities/geonames_spec.rb +2 -2
  62. data/spec/lib/authorities/linked_data/config_spec.rb +143 -0
  63. data/spec/lib/authorities/linked_data/find_term_spec.rb +5 -0
  64. data/spec/lib/authorities/linked_data/generic_authority_spec.rb +580 -0
  65. data/spec/lib/authorities/linked_data/search_config_spec.rb +385 -0
  66. data/spec/lib/authorities/linked_data/search_query_spec.rb +79 -0
  67. data/spec/lib/authorities/linked_data/term_config_spec.rb +419 -0
  68. data/spec/routing/linked_data_route_spec.rb +35 -0
  69. data/spec/spec_helper.rb +2 -0
  70. metadata +184 -39
@@ -0,0 +1,143 @@
1
+ # This module has the primary QA search method. It also includes methods to process the linked data results and convert
2
+ # them into the expected QA json results format.
3
+ module Qa::Authorities
4
+ module LinkedData
5
+ class SearchQuery
6
+ include Qa::Authorities::LinkedData::RdfHelper
7
+
8
+ # @param [SearchConfig] search_config The search portion of the config
9
+ def initialize(search_config)
10
+ @search_config = search_config
11
+ end
12
+
13
+ attr_reader :search_config
14
+
15
+ delegate :subauthority?, :supports_sort?, to: :search_config
16
+
17
+ # Search a linked data authority
18
+ # @param [String] the query
19
+ # @param [Symbol] (optional) language: language used to select literals when multi-language is supported (e.g. :en, :fr, etc.)
20
+ # @param [Hash] (optional) replacements: replacement values with { pattern_name (defined in YAML config) => value }
21
+ # @param [String] subauth: the subauthority to query
22
+ # @return [String] json results
23
+ # @example Json Results for Linked Data Search
24
+ # [ {"uri":"http://id.worldcat.org/fast/5140","id":"5140","label":"Cornell, Joseph"},
25
+ # {"uri":"http://id.worldcat.org/fast/72456","id":"72456","label":"Cornell, Sarah Maria, 1802-1832"},
26
+ # {"uri":"http://id.worldcat.org/fast/409667","id":"409667","label":"Cornell, Ezra, 1807-1874"} ]
27
+ def search(query, language: nil, replacements: {}, subauth: nil)
28
+ raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data search sub-authority #{subauth}" unless subauth.nil? || subauthority?(subauth)
29
+ language ||= search_config.language
30
+ url = search_config.url_with_replacements(query, subauth, replacements)
31
+ Rails.logger.info "QA Linked Data search url: #{url}"
32
+ graph = get_linked_data(url)
33
+ parse_search_authority_response(graph, language)
34
+ end
35
+
36
+ private
37
+
38
+ def parse_search_authority_response(graph, language)
39
+ graph = filter_language(graph, language) unless language.nil?
40
+ results = extract_preds(graph, preds_for_search)
41
+ consolidated_results = consolidate_search_results(results)
42
+ json_results = convert_search_to_json(consolidated_results)
43
+ sort_search_results(json_results)
44
+ end
45
+
46
+ def preds_for_search
47
+ { required: required_search_preds, optional: optional_search_preds }
48
+ end
49
+
50
+ def required_search_preds
51
+ label_pred_uri = search_config.results_label_predicate
52
+ raise Qa::InvalidConfiguration, "required label_predicate is missing in search configuration for LOD authority #{auth_name}" if label_pred_uri.nil?
53
+ { label: label_pred_uri }
54
+ end
55
+
56
+ def optional_search_preds
57
+ preds = {}
58
+ preds[:altlabel] = search_config.results_altlabel_predicate unless search_config.results_altlabel_predicate.nil?
59
+ preds[:id] = search_config.results_id_predicate unless search_config.results_id_predicate.nil?
60
+ preds[:sort] = search_config.results_sort_predicate unless search_config.results_sort_predicate.nil?
61
+ preds
62
+ end
63
+
64
+ def consolidate_search_results(results)
65
+ consolidated_results = {}
66
+ return consolidated_results if results.nil? || !results.count.positive?
67
+ results.each do |statement|
68
+ stmt_hash = statement.to_h
69
+ uri = stmt_hash[:uri].to_s
70
+ consolidated_hash = init_consolidated_hash(consolidated_results, uri, stmt_hash[:id].to_s)
71
+
72
+ consolidated_hash[:label] = object_value(stmt_hash, consolidated_hash, :label, false)
73
+ consolidated_hash[:altlabel] = object_value(stmt_hash, consolidated_hash, :altlabel, false)
74
+ consolidated_hash[:sort] = object_value(stmt_hash, consolidated_hash, :sort, false)
75
+ consolidated_results[uri] = consolidated_hash
76
+ end
77
+ consolidated_results.each do |res|
78
+ consolidated_hash = res[1]
79
+ consolidated_hash[:label] = sort_string_by_language consolidated_hash[:label]
80
+ consolidated_hash[:altlabel] = sort_string_by_language consolidated_hash[:altlabel]
81
+ consolidated_hash[:sort] = sort_string_by_language consolidated_hash[:sort]
82
+ end
83
+ consolidated_results
84
+ end
85
+
86
+ def convert_search_to_json(consolidated_results)
87
+ json_results = []
88
+ consolidated_results.each do |uri, h|
89
+ json_results << { uri: uri, id: h[:id], label: full_label(h[:label], h[:altlabel]), sort: h[:sort] }
90
+ end
91
+ json_results
92
+ end
93
+
94
+ def full_label(label = [], altlabel = [])
95
+ lbl = wrap_labels(label)
96
+ lbl += " (#{altlabel.join(', ')})" unless altlabel.nil? || altlabel.length <= 0
97
+ lbl = lbl.slice(0..95) + '...' if lbl.length > 98
98
+ lbl.strip
99
+ end
100
+
101
+ def wrap_labels(labels)
102
+ lbl = "" if labels.nil? || labels.size.zero?
103
+ lbl = labels.join(', ') if labels.size.positive?
104
+ lbl = '[' + lbl + ']' if labels.size > 1
105
+ lbl
106
+ end
107
+
108
+ def sort_search_results(json_results)
109
+ return json_results unless supports_sort?
110
+ json_results.sort! do |a, b|
111
+ cmp = sort_when_missing_sort_predicate(a, b)
112
+ next unless cmp.nil?
113
+
114
+ as = a[:sort].collect(&:downcase)
115
+ bs = b[:sort].collect(&:downcase)
116
+ cmp = 0
117
+ 0.upto([as.size, bs.size].max - 1) do |i|
118
+ cmp = sort_when_same_but_one_has_more_values(as, bs, i)
119
+ break unless cmp.nil?
120
+
121
+ cmp = (as[i] <=> bs[i])
122
+ break if cmp.nonzero? # stop checking as soon as a value in the two lists are different
123
+ end
124
+ cmp
125
+ end
126
+ json_results.each { |h| h.delete(:sort) }
127
+ end
128
+
129
+ def sort_when_missing_sort_predicate(a, b)
130
+ return 0 unless a.key?(:sort) || b.key?(:sort) # leave unchanged if both are missing
131
+ return -1 unless a.key? :sort # consider missing a value lower than existing b value
132
+ return 1 unless b.key? :sort # consider missing b value lower than existing a value
133
+ nil
134
+ end
135
+
136
+ def sort_when_same_but_one_has_more_values(as, bs, current_list_size)
137
+ return -1 if as.size <= current_list_size # consider shorter a list of values lower then longer b list
138
+ return 1 if bs.size <= current_list_size # consider shorter b list of values lower then longer a list
139
+ nil
140
+ end
141
+ end
142
+ end
143
+ end
@@ -1,3 +1,3 @@
1
1
  module Qa
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
@@ -0,0 +1,202 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qa::LinkedDataTermsController, type: :controller do
4
+ before do
5
+ @routes = Qa::Engine.routes
6
+ end
7
+
8
+ describe '#check_authority' do
9
+ it 'returns 404 if the vocabulary is not specified' do
10
+ expect(Rails.logger).to receive(:warn).with("Required param 'vocab' is missing or empty")
11
+ get :search, params: { q: 'a query', vocab: '' }
12
+ expect(response.code).to eq('404')
13
+ end
14
+
15
+ it 'returns 404 if the vocabulary is not specified' do
16
+ expect(Rails.logger).to receive(:warn).with("Required param 'vocab' is missing or empty")
17
+ get :show, params: { id: 'C_1234', vocab: '' }
18
+ expect(response.code).to eq('404')
19
+ end
20
+ end
21
+
22
+ describe '#check_search_subauthority' do
23
+ it 'returns 404 if the query subauthority is missing' do
24
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data search sub-authority '' for authority 'OCLC_FAST'")
25
+ get :search, params: { q: 'test', vocab: 'OCLC_FAST', subauthority: '' }
26
+ expect(response.code).to eq('404')
27
+ end
28
+ it 'returns 404 if the query subauthority is invalid' do
29
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data search sub-authority 'FAKE_SUBAUTHORITY' for authority 'OCLC_FAST'")
30
+ get :search, params: { vocab: 'OCLC_FAST', subauthority: 'FAKE_SUBAUTHORITY' }
31
+ expect(response.code).to eq('404')
32
+ end
33
+ end
34
+
35
+ describe '#check_show_subauthority' do
36
+ it 'returns 404 if the show subauthority is missing' do
37
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data term sub-authority '' for authority 'OCLC_FAST'")
38
+ get :show, params: { id: 'C_123', vocab: 'OCLC_FAST', subauthority: '' }
39
+ expect(response.code).to eq('404')
40
+ end
41
+ it 'returns 404 if the show subauthority is invalid' do
42
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data term sub-authority 'FAKE_SUBAUTHORITY' for authority 'OCLC_FAST'")
43
+ get :show, params: { id: 'C_123', vocab: 'OCLC_FAST', subauthority: 'FAKE_SUBAUTHORITY' }
44
+ expect(response.code).to eq('404')
45
+ end
46
+ end
47
+
48
+ describe '#check_query_param' do
49
+ it 'returns 404 if the query is missing' do
50
+ expect(Rails.logger).to receive(:warn).with("Required search param 'q' is missing or empty")
51
+ get :search, params: { vocab: 'OCLC_FAST' }
52
+ expect(response.code).to eq('404')
53
+ end
54
+ end
55
+
56
+ describe '#check_id_param' do
57
+ it 'returns 404 if the id is missing' do
58
+ expect(Rails.logger).to receive(:warn).with("Required show param 'id' is missing or empty")
59
+ get :show, params: { id: '', vocab: 'OCLC_FAST' }
60
+ expect(response.code).to eq('404')
61
+ end
62
+ end
63
+
64
+ describe '#init_authority' do
65
+ context 'when the authority does not exist' do
66
+ it 'returns 404' do
67
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data authority 'FAKE_AUTHORITY'")
68
+ get :search, params: { q: 'a query', vocab: 'fake_authority' }
69
+ expect(response.code).to eq('404')
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#search' do
75
+ context 'in OCLC_FAST authority' do
76
+ context '0 search results' do
77
+ before do
78
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=cql.any%20all%20%22supercalifragilisticexpialidocious%22&sortKeys=usage')
79
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_query_no_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
80
+ end
81
+ it 'succeeds' do
82
+ get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'OCLC_FAST', maximumRecords: '3' }
83
+ expect(response).to be_success
84
+ end
85
+ end
86
+
87
+ context '3 search results' do
88
+ before do
89
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=cql.any%20all%20%22cornell%22&sortKeys=usage')
90
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_all_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
91
+ end
92
+ it 'succeeds' do
93
+ get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', maximumRecords: '3' }
94
+ expect(response).to be_success
95
+ end
96
+ end
97
+ end
98
+
99
+ context 'in OCLC_FAST authority and personal_name subauthority' do
100
+ context '0 search results' do
101
+ before do
102
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22supercalifragilisticexpialidocious%22&sortKeys=usage')
103
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_query_no_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
104
+ end
105
+ it 'succeeds' do
106
+ get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
107
+ expect(response).to be_success
108
+ end
109
+ end
110
+
111
+ context '3 search results' do
112
+ before do
113
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22cornell%22&sortKeys=usage')
114
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_personalName_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
115
+ end
116
+ it 'succeeds' do
117
+ get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
118
+ expect(response).to be_success
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'in AGROVOC authority' do
124
+ context '0 search results' do
125
+ before do
126
+ stub_request(:get, 'http://aims.fao.org/skosmos/rest/v1/search/?lang=en&query=*supercalifragilisticexpialidocious*')
127
+ .to_return(status: 200, body: webmock_fixture('lod_agrovoc_query_no_results.json'), headers: { 'Content-Type' => 'application/json' })
128
+ end
129
+ it 'succeeds' do
130
+ get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'AGROVOC' }
131
+ expect(response).to be_success
132
+ end
133
+ end
134
+
135
+ context '3 search results' do
136
+ before do
137
+ stub_request(:get, 'http://aims.fao.org/skosmos/rest/v1/search/?lang=en&query=*milk*')
138
+ .to_return(status: 200, body: webmock_fixture('lod_agrovoc_query_many_results.json'), headers: { 'Content-Type' => 'application/json' })
139
+ end
140
+ it 'succeeds' do
141
+ get :search, params: { q: 'milk', vocab: 'AGROVOC' }
142
+ expect(response).to be_success
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#show' do
149
+ context 'basic parameter testing' do
150
+ context 'with bad id' do
151
+ before do
152
+ stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID')
153
+ .to_return(status: 404, body: '', headers: {})
154
+ end
155
+ it 'returns 404' do
156
+ expect(Rails.logger).to receive(:warn).with('Term Not Found - Fetch term FAKE_ID unsuccessful for authority OCLC_FAST')
157
+ get :show, params: { id: 'FAKE_ID', vocab: 'OCLC_FAST' }
158
+ expect(response.code).to eq('404')
159
+ end
160
+ end
161
+ end
162
+
163
+ context 'in OCLC_FAST authority' do
164
+ context 'term found' do
165
+ before do
166
+ stub_request(:get, 'http://id.worldcat.org/fast/530369')
167
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
168
+ end
169
+ it 'succeeds' do
170
+ get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
171
+ expect(response).to be_success
172
+ end
173
+ end
174
+ end
175
+
176
+ context 'in AGROVOC authority' do
177
+ context 'term found' do
178
+ before do
179
+ stub_request(:get, 'http://aims.fao.org/skosmos/rest/v1/data?uri=http://aims.fao.org/aos/agrovoc/c_9513')
180
+ .to_return(status: 200, body: webmock_fixture('lod_agrovoc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
181
+ end
182
+ it 'succeeds' do
183
+ get :show, params: { id: 'c_9513', vocab: 'AGROVOC' }
184
+ expect(response).to be_success
185
+ end
186
+ end
187
+ end
188
+
189
+ context 'in LOC authority' do
190
+ context 'term found' do
191
+ before do
192
+ stub_request(:get, 'http://id.loc.gov/authorities/subjects/sh85118553')
193
+ .to_return(status: 200, body: webmock_fixture('lod_loc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
194
+ end
195
+ it 'succeeds' do
196
+ get :show, params: { id: 'sh85118553', vocab: 'LOC', subauthority: 'subjects' }
197
+ expect(response).to be_success
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,111 @@
1
+ {
2
+ "term": {
3
+ "url": {
4
+ "@context": "http://www.w3.org/ns/hydra/context.jsonld",
5
+ "@type": "IriTemplate",
6
+ "template": "http://localhost/test_default/term/{?subauth}/{?term_id}?param1={?param1}&param2={?param2}",
7
+ "variableRepresentation": "BasicRepresentation",
8
+ "mapping": [
9
+ {
10
+ "@type": "IriTemplateMapping",
11
+ "variable": "term_id",
12
+ "property": "hydra:freetextQuery",
13
+ "required": true
14
+ },
15
+ {
16
+ "@type": "IriTemplateMapping",
17
+ "variable": "subauth",
18
+ "property": "hydra:freetextQuery",
19
+ "required": false,
20
+ "default": "term_sub2_name"
21
+ },
22
+ {
23
+ "@type": "IriTemplateMapping",
24
+ "variable": "param1",
25
+ "property": "hydra:freetextQuery",
26
+ "required": false,
27
+ "default": "alpha"
28
+ },
29
+ {
30
+ "@type": "IriTemplateMapping",
31
+ "variable": "param2",
32
+ "property": "hydra:freetextQuery",
33
+ "required": false,
34
+ "default": "beta"
35
+ }
36
+ ]
37
+ },
38
+ "qa_replacement_patterns": {
39
+ "term_id": "term_id",
40
+ "subauth": "subauth"
41
+ },
42
+ "term_id": "ID",
43
+ "language": [ "en" ],
44
+ "results": {
45
+ "id_predicate": "http://purl.org/dc/terms/identifier",
46
+ "label_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel",
47
+ "altlabel_predicate": "http://www.w3.org/2004/02/skos/core#altLabel",
48
+ "broader_predicate": "http://www.w3.org/2004/02/skos/core#broader",
49
+ "narrower_predicate": "http://www.w3.org/2004/02/skos/core#narrower",
50
+ "sameas_predicate": "http://www.w3.org/2004/02/skos/core#exactMatch"
51
+ },
52
+ "subauthorities": {
53
+ "term_sub1_key": "term_sub1_name",
54
+ "term_sub2_key": "term_sub2_name",
55
+ "term_sub3_key": "term_sub3_name"
56
+ }
57
+ },
58
+ "search": {
59
+ "url": {
60
+ "@context": "http://www.w3.org/ns/hydra/context.jsonld",
61
+ "@type": "IriTemplate",
62
+ "template": "http://localhost/test_default/search?subauth={?subauth}&query={?query}&param1={?param1}&param2={?param2}",
63
+ "variableRepresentation": "BasicRepresentation",
64
+ "mapping": [
65
+ {
66
+ "@type": "IriTemplateMapping",
67
+ "variable": "query",
68
+ "property": "hydra:freetextQuery",
69
+ "required": true
70
+ },
71
+ {
72
+ "@type": "IriTemplateMapping",
73
+ "variable": "subauth",
74
+ "property": "hydra:freetextQuery",
75
+ "required": false,
76
+ "default": "search_sub1_name"
77
+ },
78
+ {
79
+ "@type": "IriTemplateMapping",
80
+ "variable": "param1",
81
+ "property": "hydra:freetextQuery",
82
+ "required": false,
83
+ "default": "delta"
84
+ },
85
+ {
86
+ "@type": "IriTemplateMapping",
87
+ "variable": "param2",
88
+ "property": "hydra:freetextQuery",
89
+ "required": false,
90
+ "default": "echo"
91
+ }
92
+ ]
93
+ },
94
+ "qa_replacement_patterns": {
95
+ "query": "query",
96
+ "subauth": "subauth"
97
+ },
98
+ "language": [ "en", "fr", "de" ],
99
+ "results": {
100
+ "id_predicate": "http://purl.org/dc/terms/identifier",
101
+ "label_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel",
102
+ "altlabel_predicate": "http://www.w3.org/2004/02/skos/core#altLabel",
103
+ "sort_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel"
104
+ },
105
+ "subauthorities": {
106
+ "search_sub1_key": "search_sub1_name",
107
+ "search_sub2_key": "search_sub2_name",
108
+ "search_sub3_key": "search_sub3_name"
109
+ }
110
+ }
111
+ }