celsius-primo 0.1.3 → 0.1.4
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/celsius-primo.gemspec +2 -1
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/add_sort_by_list.rb +24 -19
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/add_missing_facets.rb +23 -31
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/process_records.rb +9 -10
- data/lib/celsius/primo/version.rb +1 -1
- data/spec/assets/adapter/search/{complex_search_request.yml → scenarios/complex_request/search_request.yml} +0 -0
- data/spec/assets/adapter/search/{search_result_for_complex_request.yml → scenarios/complex_request/search_result.yml} +0 -0
- data/spec/assets/adapter/search/{search_request_with_empty_result.yml → scenarios/empty_result/search_request.yml} +0 -0
- data/spec/assets/adapter/search/{empty_search_result.yml → scenarios/empty_result/search_result.yml} +0 -0
- data/spec/assets/adapter/search/scenarios/missing_facets/search_request.yml +66 -0
- data/spec/assets/adapter/search/scenarios/missing_facets/search_result.yml +158 -0
- data/spec/assets/adapter/search/{search_request_for_multiple_publishers.yml → scenarios/result_with_multiple_publishers/search_request.yml} +0 -0
- data/spec/assets/adapter/search/{search_result_with_multiple_publishers.yml → scenarios/result_with_multiple_publishers/search_result.yml} +17 -15
- data/spec/assets/adapter/search/{search_request.yml → scenarios/simple_request/search_request.yml} +0 -0
- data/spec/assets/adapter/search/{search_result.yml → scenarios/simple_request/search_result.yml} +45 -20
- data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_complex_request_.yml +191 -0
- data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_empty_result_.yml +88 -0
- data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_missing_facets_.yml +162 -0
- data/spec/cassettes/Celsius_Primo_Adapter/_search/{returns_a_normalized_search_result.yml → passes_the_scenario_result_with_multiple_publishers_.yml} +46 -1484
- data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_simple_request_.yml +1169 -0
- data/spec/celsius-primo/adapter_spec.rb +15 -12
- metadata +50 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4efed52d11b5b38d7bbe6a76fe4196b3cac0e617
|
4
|
+
data.tar.gz: 7eef803681d80fb6392a8cc38bc0aa700cf836d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfdb2a0f4066ee4744353f9ca2b0465776304ff1014f0a46b8eabf96eec744da9abbdac173114fe310e9d4b51b3f589e2c54abf3d3c0c8e1e32eef21cce78844
|
7
|
+
data.tar.gz: 4603cab36760f66831bbd13e5cc2d896cd421bbdde5a0f5da90aacbdfae4dcf22974ac86ced8b61cf31f45173ae98ffc32b60a7c9ea7011117d5f11601089897
|
data/Gemfile
CHANGED
data/celsius-primo.gemspec
CHANGED
@@ -18,11 +18,12 @@ Gem::Specification.new do |spec|
|
|
18
18
|
|
19
19
|
spec.add_dependency "celsius", ">= 0.4.3"
|
20
20
|
spec.add_dependency "httpi", ">= 2.1.0", "< 3.0.0"
|
21
|
+
spec.add_dependency "hashie"
|
21
22
|
spec.add_dependency "ox", ">= 2.1.0"
|
22
23
|
|
23
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
25
|
spec.add_development_dependency "rake"
|
25
|
-
spec.add_development_dependency "rspec", ">= 3.0.0", "<
|
26
|
+
spec.add_development_dependency "rspec", ">= 3.0.0", "< 3.2.0"
|
26
27
|
spec.add_development_dependency "simplecov", ">= 0.8.0"
|
27
28
|
spec.add_development_dependency "vcr", ">= 2.9.0", "< 3.0.0"
|
28
29
|
spec.add_development_dependency "webmock", ">= 1.19.0", "< 2.0.0"
|
@@ -9,28 +9,33 @@ class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchRequestTransformatio
|
|
9
9
|
#
|
10
10
|
def call
|
11
11
|
if sort_fields = (Celsius::Hash.deep_find_key(source, :sort) || []).first
|
12
|
-
# map sort field values to primo equivalents
|
13
|
-
primo_sort_fields = sort_fields.map(&transformation.method(:sort_field_mapping))
|
14
|
-
|
15
|
-
# memoize this node to shorten further lines
|
16
12
|
primo_search_request = transformation.inner_search_request.locate("PrimoSearchRequest").first
|
13
|
+
insert_sort_by_node(primo_search_request, sort_fields)
|
14
|
+
end
|
15
|
+
end
|
17
16
|
|
18
|
-
# Order matters, SortField *must* be inserted after <Languages>
|
19
|
-
index_of_languages = primo_search_request.nodes.index do |node|
|
20
|
-
node.value == "Languages"
|
21
|
-
end
|
22
|
-
|
23
|
-
# primo can only handle *one* sort field
|
24
|
-
sort_by_list = Ox.parse(
|
25
|
-
<<-xml
|
26
|
-
<SortByList>
|
27
|
-
<SortField>#{primo_sort_fields.first}</SortField>
|
28
|
-
</SortByList>
|
29
|
-
xml
|
30
|
-
)
|
31
17
|
|
32
|
-
|
33
|
-
|
18
|
+
#
|
19
|
+
private
|
20
|
+
#
|
21
|
+
def insert_sort_by_node(primo_search_request, sort_fields)
|
22
|
+
# Order matters, SortField *must* be inserted after <Languages>
|
23
|
+
index_of_languages = primo_search_request.nodes.index do |node|
|
24
|
+
node.value == "Languages"
|
34
25
|
end
|
26
|
+
|
27
|
+
# primo can only handle *one* sort field
|
28
|
+
sort_field = transformation.sort_field_mapping(sort_fields.first)
|
29
|
+
|
30
|
+
sort_by_list = Ox.parse(
|
31
|
+
<<-xml
|
32
|
+
<SortByList>
|
33
|
+
<SortField>#{sort_field}</SortField>
|
34
|
+
</SortByList>
|
35
|
+
xml
|
36
|
+
)
|
37
|
+
|
38
|
+
# insert the SortByList at the appropriate position
|
39
|
+
primo_search_request.nodes.insert(index_of_languages + 1, sort_by_list)
|
35
40
|
end
|
36
41
|
end
|
@@ -1,17 +1,31 @@
|
|
1
1
|
require "celsius/transformation/step"
|
2
|
-
require "
|
2
|
+
require "hashie/extensions/deep_locate"
|
3
3
|
|
4
4
|
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
5
5
|
AddMissingFacets < Celsius::Transformation::Step
|
6
6
|
|
7
|
-
#
|
8
|
-
# Sometimes, requested facets do not show up in search result, so we have to (re)add them
|
9
|
-
#
|
7
|
+
# handle primo bug where requested facets don't show up in search response
|
10
8
|
def call
|
11
9
|
(search_request["facets"] || {}).each do |facet_name, requested_facet|
|
10
|
+
# case 1 - there is no facet at all
|
12
11
|
unless target["facets"][facet_name]
|
13
12
|
if requested_facet["terms"]
|
14
|
-
target["facets"][facet_name] =
|
13
|
+
target["facets"][facet_name] = search_result_terms_facet
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# case 2 - there is a facet, but the requested facet is not included
|
19
|
+
facet_queries = deep_locate(-> (key, value, object) {
|
20
|
+
key == "match" && value.keys.any? { |key_| key_.start_with?("facet") }
|
21
|
+
}, search_request)
|
22
|
+
|
23
|
+
facet_queries.each do |facet_query|
|
24
|
+
facet_query["match"].tap do |match|
|
25
|
+
target["facets"][match.keys.first]["terms"].tap do |facet_terms|
|
26
|
+
if facet_terms.none? { |term| term["term"] == match.values.first }
|
27
|
+
facet_terms << { "term" => match.values.first, "count" => 1 }
|
28
|
+
end
|
15
29
|
end
|
16
30
|
end
|
17
31
|
end
|
@@ -20,36 +34,14 @@ class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation
|
|
20
34
|
#
|
21
35
|
private
|
22
36
|
#
|
23
|
-
def
|
37
|
+
def search_result_terms_facet(terms = [])
|
24
38
|
{
|
25
39
|
"_type" => "terms",
|
26
|
-
"terms" =>
|
40
|
+
"terms" => terms
|
27
41
|
}
|
28
42
|
end
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
process "//match", source: -> { @search_request} do |match, target|
|
33
|
-
if (target_facet_name = match.nodes.first.value).start_with?("facet_")
|
34
|
-
target_facet_value = match.nodes.first.text
|
35
|
-
target_facet_count = find_all(@search_brief_return, "SEGMENTS/JAGROOT/RESULT/DOCSET/DOC").length
|
36
|
-
|
37
|
-
# case 1 - there is no facet at all
|
38
|
-
unless find(target, "facets/#{target_facet_name}")
|
39
|
-
find(target, "facets") << element(target_facet_name) do |target_facet|
|
40
|
-
target_facet << element("_type", text: "terms")
|
41
|
-
target_facet << array("terms")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# case 2 - there is a facet, but the requested facet is not included
|
46
|
-
unless find_all(target, "facets/#{target_facet_name}/terms/terms/term").map(&:text).include?(target_facet_value)
|
47
|
-
array(find(target, "facets/#{target_facet_name}/terms")) do |term|
|
48
|
-
term << element("term", text: target_facet_value)
|
49
|
-
term << element("count", text: target_facet_count.to_s, type: "integer")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
44
|
+
def deep_locate(*args)
|
45
|
+
Hashie::Extensions::DeepLocate.deep_locate(*args)
|
53
46
|
end
|
54
|
-
=end
|
55
47
|
end
|
@@ -38,20 +38,19 @@ class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation
|
|
38
38
|
#
|
39
39
|
def add_place_of_publication!(record)
|
40
40
|
if record["publisher"] && !record["placeOfPublication"]
|
41
|
-
record["
|
42
|
-
|
41
|
+
places_seperated_from_publishers = ensure_array(record["publisher"]).map do |publisher|
|
42
|
+
publisher.match(/(\A[^:]*):(.*)/).captures.map(&:strip)
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
publisher.match(/(\A[^:]*):(.*)/) do |match|
|
46
|
-
_place_of_publication, _publisher = match.captures.map(&:strip)
|
45
|
+
places_of_publication, publishers = [], []
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
places_seperated_from_publishers.each.with_index do |place_and_publisher, index|
|
48
|
+
places_of_publication[index] = place_and_publisher.first
|
49
|
+
publishers[index] = place_and_publisher.last
|
51
50
|
end
|
52
51
|
|
53
|
-
record["placeOfPublication"] = collapse_array(
|
54
|
-
record["publisher"] = collapse_array(
|
52
|
+
record["placeOfPublication"] = collapse_array(places_of_publication)
|
53
|
+
record["publisher"] = collapse_array(publishers)
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
File without changes
|
File without changes
|
File without changes
|
data/spec/assets/adapter/search/{empty_search_result.yml → scenarios/empty_result/search_result.yml}
RENAMED
File without changes
|
@@ -0,0 +1,66 @@
|
|
1
|
+
---
|
2
|
+
facets:
|
3
|
+
facet_tlevel:
|
4
|
+
terms:
|
5
|
+
field: facet_tlevel
|
6
|
+
shard_size: 75
|
7
|
+
facet_creator:
|
8
|
+
terms:
|
9
|
+
field: facet_creator
|
10
|
+
shard_size: 75
|
11
|
+
facet_local31:
|
12
|
+
terms:
|
13
|
+
field: facet_local31
|
14
|
+
shard_size: 75
|
15
|
+
facet_topic:
|
16
|
+
terms:
|
17
|
+
field: facet_topic
|
18
|
+
shard_size: 75
|
19
|
+
facet_creationdate:
|
20
|
+
terms:
|
21
|
+
field: facet_creationdate
|
22
|
+
shard_size: 75
|
23
|
+
facet_domain:
|
24
|
+
terms:
|
25
|
+
field: facet_domain
|
26
|
+
shard_size: 75
|
27
|
+
facet_lang:
|
28
|
+
terms:
|
29
|
+
field: facet_lang
|
30
|
+
shard_size: 75
|
31
|
+
facet_local15:
|
32
|
+
terms:
|
33
|
+
field: facet_local15
|
34
|
+
shard_size: 75
|
35
|
+
facet_local32:
|
36
|
+
terms:
|
37
|
+
field: facet_local32
|
38
|
+
shard_size: 75
|
39
|
+
facet_local33:
|
40
|
+
terms:
|
41
|
+
field: facet_local33
|
42
|
+
shard_size: 75
|
43
|
+
from: 0
|
44
|
+
size: 20
|
45
|
+
sort:
|
46
|
+
- _score
|
47
|
+
query:
|
48
|
+
bool:
|
49
|
+
must:
|
50
|
+
- query_string:
|
51
|
+
default_operator: AND
|
52
|
+
fields:
|
53
|
+
- _all
|
54
|
+
query: linux
|
55
|
+
- query_string:
|
56
|
+
default_operator: AND
|
57
|
+
fields:
|
58
|
+
- creator
|
59
|
+
query: kofler
|
60
|
+
- query_string:
|
61
|
+
default_operator: AND
|
62
|
+
fields:
|
63
|
+
- _all
|
64
|
+
query: mysql
|
65
|
+
- match:
|
66
|
+
facet_topic: MySQL
|
@@ -0,0 +1,158 @@
|
|
1
|
+
---
|
2
|
+
took:
|
3
|
+
hits:
|
4
|
+
hits:
|
5
|
+
- _type: record
|
6
|
+
_source:
|
7
|
+
control:
|
8
|
+
sourcerecordid: 000831395
|
9
|
+
sourceid: PAD_ALEPH
|
10
|
+
recordid: PAD_ALEPH000831395
|
11
|
+
originalsourceid: PAD01
|
12
|
+
ilsapiid: PAD01000831395
|
13
|
+
sourcesystem: Aleph
|
14
|
+
display:
|
15
|
+
type: print
|
16
|
+
title: 'MySQL : Einführung, Programmierung, Referenz'
|
17
|
+
creator: Kofler, Michael
|
18
|
+
publisher: 'München [u.a.] : Addison-Wesley'
|
19
|
+
creationdate: '2001'
|
20
|
+
format: '624 S. : Ill., graph. Darst.'
|
21
|
+
subject: MySQL
|
22
|
+
language: ger
|
23
|
+
lds01: '{"ht_number":null,"label":"Linux Specials","volume_count":null,"label_additions":null}'
|
24
|
+
lds02: 'MySQL : Einführung, Programmierung, Referenz'
|
25
|
+
lds10: TWY9467
|
26
|
+
search:
|
27
|
+
creatorcontrib:
|
28
|
+
- Kofler, Michael
|
29
|
+
- Kofler, M.
|
30
|
+
- Kofler, Michaėlʹ
|
31
|
+
title:
|
32
|
+
- 'MySQL : Einführung, Programmierung, Referenz'
|
33
|
+
- Linux Specials
|
34
|
+
subject: MySQL
|
35
|
+
general: TWY
|
36
|
+
sourceid: PAD_ALEPH
|
37
|
+
recordid: PAD_ALEPH000831395
|
38
|
+
isbn:
|
39
|
+
- 3-8273-1762-2
|
40
|
+
- '9783827317629'
|
41
|
+
- '3827317622'
|
42
|
+
rsrctype: print
|
43
|
+
format: '624 S. : Ill., graph. Darst.'
|
44
|
+
creationdate: '2001'
|
45
|
+
searchscope: PAD_ALEPH
|
46
|
+
scope: PAD_ALEPH
|
47
|
+
lsr02: 'false'
|
48
|
+
lsr03: 'false'
|
49
|
+
lsr04: 'true'
|
50
|
+
lsr05: HT012953391
|
51
|
+
lsr09: '20010522'
|
52
|
+
lsr10:
|
53
|
+
- TWY9467
|
54
|
+
- TWY9467+1
|
55
|
+
- TWY9467+2
|
56
|
+
- TWY9467+3
|
57
|
+
lsr15: TWY
|
58
|
+
lsr31: monograph
|
59
|
+
lsr32: other
|
60
|
+
lsr33: print
|
61
|
+
lsr34: 'München [u.a.] : Addison-Wesley'
|
62
|
+
sort:
|
63
|
+
title: 'MySQL : Einführung, Programmierung, Referenz'
|
64
|
+
creationdate: '2001'
|
65
|
+
author: Kofler, Michael
|
66
|
+
lso01: '20010522'
|
67
|
+
lso03: TWY
|
68
|
+
lso48: PAD01000831395
|
69
|
+
facets:
|
70
|
+
language: ger
|
71
|
+
creationdate: '2001'
|
72
|
+
topic: MySQL
|
73
|
+
toplevel: printmedia
|
74
|
+
rsrctype:
|
75
|
+
- other
|
76
|
+
- books
|
77
|
+
creatorcontrib: Kofler, Michael
|
78
|
+
format: '624 S. : Ill., graph. Darst.'
|
79
|
+
lfc15: TWY
|
80
|
+
lfc31: monograph
|
81
|
+
lfc32: other
|
82
|
+
lfc33: print
|
83
|
+
frbrgroupid: '282131342'
|
84
|
+
frbrtype: '6'
|
85
|
+
delivery:
|
86
|
+
delcategory: physical_item
|
87
|
+
addata:
|
88
|
+
lad01: '{"author_statement":["Michael Kofler"],"person_creator_display":["Kofler,
|
89
|
+
Michael"]}'
|
90
|
+
_id: PAD_ALEPH000831395
|
91
|
+
creator: Kofler, Michael
|
92
|
+
created: '2001'
|
93
|
+
description:
|
94
|
+
edition:
|
95
|
+
format: '624 S. : Ill., graph. Darst.'
|
96
|
+
identifier:
|
97
|
+
- PAD01000831395
|
98
|
+
- PAD_ALEPH000831395
|
99
|
+
isbn:
|
100
|
+
- 3-8273-1762-2
|
101
|
+
- '9783827317629'
|
102
|
+
- '3827317622'
|
103
|
+
issn:
|
104
|
+
language: ger
|
105
|
+
title: 'MySQL : Einführung, Programmierung, Referenz'
|
106
|
+
publisher: Addison-Wesley
|
107
|
+
subject: MySQL
|
108
|
+
placeOfPublication: München [u.a.]
|
109
|
+
total: 1
|
110
|
+
facets:
|
111
|
+
facet_tlevel:
|
112
|
+
_type: terms
|
113
|
+
terms:
|
114
|
+
- term: printmedia
|
115
|
+
count: 1
|
116
|
+
facet_creator:
|
117
|
+
_type: terms
|
118
|
+
terms:
|
119
|
+
- term: Kofler, Michael
|
120
|
+
count: 1
|
121
|
+
facet_local31:
|
122
|
+
_type: terms
|
123
|
+
terms:
|
124
|
+
- term: monograph
|
125
|
+
count: 1
|
126
|
+
facet_topic:
|
127
|
+
_type: terms
|
128
|
+
terms:
|
129
|
+
- term: MySQL
|
130
|
+
count: 1
|
131
|
+
facet_creationdate:
|
132
|
+
_type: terms
|
133
|
+
terms:
|
134
|
+
- term: '2001'
|
135
|
+
count: 1
|
136
|
+
facet_domain:
|
137
|
+
_type: terms
|
138
|
+
terms: []
|
139
|
+
facet_lang:
|
140
|
+
_type: terms
|
141
|
+
terms:
|
142
|
+
- term: ger
|
143
|
+
count: 1
|
144
|
+
facet_local15:
|
145
|
+
_type: terms
|
146
|
+
terms:
|
147
|
+
- term: TWY
|
148
|
+
count: 1
|
149
|
+
facet_local32:
|
150
|
+
_type: terms
|
151
|
+
terms:
|
152
|
+
- term: other
|
153
|
+
count: 1
|
154
|
+
facet_local33:
|
155
|
+
_type: terms
|
156
|
+
terms:
|
157
|
+
- term: print
|
158
|
+
count: 1
|
File without changes
|
@@ -3127,12 +3127,26 @@ facets:
|
|
3127
3127
|
facet_topic:
|
3128
3128
|
_type: terms
|
3129
3129
|
terms:
|
3130
|
-
- term: SHELL
|
3131
|
-
count: 5
|
3132
3130
|
- term: Rechnernetz
|
3133
3131
|
count: 10
|
3134
3132
|
- term: Personalcomputer
|
3135
3133
|
count: 5
|
3134
|
+
- term: Computer science
|
3135
|
+
count: 9
|
3136
|
+
- term: Unternehmen
|
3137
|
+
count: 4
|
3138
|
+
- term: Eingebettetes System
|
3139
|
+
count: 5
|
3140
|
+
- term: Kernel
|
3141
|
+
count: 5
|
3142
|
+
- term: Programmierung
|
3143
|
+
count: 6
|
3144
|
+
- term: Python
|
3145
|
+
count: 4
|
3146
|
+
- term: Software Engineering
|
3147
|
+
count: 12
|
3148
|
+
- term: SHELL
|
3149
|
+
count: 5
|
3136
3150
|
- term: Web-Seite
|
3137
3151
|
count: 7
|
3138
3152
|
- term: c
|
@@ -3143,34 +3157,22 @@ facets:
|
|
3143
3157
|
count: 8
|
3144
3158
|
- term: Operating systems (Computers)
|
3145
3159
|
count: 14
|
3146
|
-
- term: Computer science
|
3147
|
-
count: 9
|
3148
3160
|
- term: Treiber
|
3149
3161
|
count: 5
|
3150
|
-
- term:
|
3162
|
+
- term: Server
|
3151
3163
|
count: 4
|
3152
3164
|
- term: UNIX
|
3153
3165
|
count: 23
|
3154
|
-
- term: Eingebettetes System
|
3155
|
-
count: 5
|
3156
3166
|
- term: Open Source
|
3157
3167
|
count: 6
|
3158
3168
|
- term: Computersicherheit
|
3159
3169
|
count: 6
|
3160
3170
|
- term: Systemverwaltung
|
3161
3171
|
count: 6
|
3162
|
-
- term: Kernel
|
3163
|
-
count: 5
|
3164
|
-
- term: Programmierung
|
3165
|
-
count: 6
|
3166
3172
|
- term: Softwareentwicklung
|
3167
3173
|
count: 7
|
3168
3174
|
- term: Betriebssystem
|
3169
3175
|
count: 9
|
3170
|
-
- term: Python
|
3171
|
-
count: 4
|
3172
|
-
- term: Software engineering
|
3173
|
-
count: 12
|
3174
3176
|
- term: Gestaltung
|
3175
3177
|
count: 5
|
3176
3178
|
- term: Computer network architectures
|