celsius-primo 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|