celsius-primo 0.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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +6 -0
- data/celsius-primo.gemspec +29 -0
- data/lib/celsius/primo/adapter/mget.rb +36 -0
- data/lib/celsius/primo/adapter/operation.rb +17 -0
- data/lib/celsius/primo/adapter/search.rb +28 -0
- data/lib/celsius/primo/adapter.rb +52 -0
- data/lib/celsius/primo/locales/de.yml +455 -0
- data/lib/celsius/primo/locales/en.yml +207 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/add_sort_by_list.rb +36 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/embed_inner_search_request.rb +12 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/process_ids_queries.rb +29 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/process_match_queries.rb +29 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/process_query_string_queries.rb +37 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/process_range_queries.rb +28 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/serialize_target_as_xml.rb +10 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/set_bulk_size.rb +12 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/set_institution.rb +12 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/set_languages.rb +14 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/set_locations.rb +17 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/set_start_index.rb +12 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/setup_inner_search_request.rb +32 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/setup_target.rb +25 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation.rb +59 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/add_missing_facets.rb +45 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/parse_inner_search_brief_return.rb +23 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/process_facets.rb +29 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/process_records.rb +80 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/remove_bogus_creationdate_facets.rb +15 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/select_only_requested_facets.rb +14 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/set_total_hits.rb +12 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/setup_target_skeleton.rb +17 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/sort_facets_by_search_request.rb +21 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation.rb +59 -0
- data/lib/celsius/primo/soap_api/searcher/search_brief.rb +56 -0
- data/lib/celsius/primo/soap_api/searcher.rb +14 -0
- data/lib/celsius/primo/soap_api.rb +22 -0
- data/lib/celsius/primo/version.rb +5 -0
- data/lib/celsius/primo.rb +7 -0
- data/spec/assets/adapter/mget/mget_request.yml +4 -0
- data/spec/assets/adapter/mget/mget_result.yml +407 -0
- data/spec/assets/adapter/search/search_request.yml +59 -0
- data/spec/assets/adapter/search/search_result.yml +1517 -0
- data/spec/cassettes/Celsius_Primo_Adapter/_mget/returns_a_normalzed_mget_result.yml +396 -0
- data/spec/cassettes/Celsius_Primo_Adapter/_search/returns_a_normalized_search_result.yml +1169 -0
- data/spec/celsius-primo/adapter_spec.rb +56 -0
- data/spec/celsius-primo_spec.rb +6 -0
- data/spec/spec_helper.rb +55 -0
- metadata +255 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchRequestTransformation::
|
|
5
|
+
SetStartIndex < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
transformation.inner_search_request.locate("PrimoSearchRequest/StartIndex").first.tap do |node|
|
|
9
|
+
node << (Celsius::Hash.deep_find_key(source, :from).first.to_i + 1).to_s
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchRequestTransformation::
|
|
5
|
+
SetupInnerSearchRequest < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# setup inner search request that will be wrapped in a cdata element at the end
|
|
9
|
+
#
|
|
10
|
+
def call
|
|
11
|
+
# we setup this skeleton instead of dynamic element creation because order matters with primo
|
|
12
|
+
transformation.inner_search_request = Ox.parse(
|
|
13
|
+
<<-xml
|
|
14
|
+
<searchRequest xmlns="http://www.exlibris.com/primo/xsd/wsRequest" xmlns:uic="http://www.exlibris.com/primo/xsd/primoview/uicomponents">
|
|
15
|
+
<PrimoSearchRequest xmlns="http://www.exlibris.com/primo/xsd/search/request">
|
|
16
|
+
<QueryTerms>
|
|
17
|
+
<BoolOpeator></BoolOpeator>
|
|
18
|
+
</QueryTerms>
|
|
19
|
+
<StartIndex></StartIndex>
|
|
20
|
+
<BulkSize></BulkSize>
|
|
21
|
+
<DidUMeanEnabled>false</DidUMeanEnabled>
|
|
22
|
+
<HighlightingEnabled>false</HighlightingEnabled>
|
|
23
|
+
<Languages></Languages>
|
|
24
|
+
<Locations></Locations>
|
|
25
|
+
</PrimoSearchRequest>
|
|
26
|
+
<onCampus>false</onCampus>
|
|
27
|
+
<institution></institution>
|
|
28
|
+
</searchRequest>
|
|
29
|
+
xml
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/setup_target.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchRequestTransformation::SetupTarget < Celsius::Transformation::Step
|
|
5
|
+
def call
|
|
6
|
+
# create empty ox document
|
|
7
|
+
self.target = Ox::Document.new(version: "1.0", encoding: "UTF-8")
|
|
8
|
+
|
|
9
|
+
# populate target with soap request skeleton
|
|
10
|
+
self.target << Ox.parse(
|
|
11
|
+
<<-xml
|
|
12
|
+
<env:Envelope
|
|
13
|
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
14
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
15
|
+
xmlns:impl="http://primo.kobv.de/PrimoWebServices/services/searcher"
|
|
16
|
+
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
|
17
|
+
xmlns:ins0="http://xml.apache.org/xml-soap">
|
|
18
|
+
<env:Body>
|
|
19
|
+
<impl:searchBrief><searchRequestStr></searchRequestStr></impl:searchBrief>
|
|
20
|
+
</env:Body>
|
|
21
|
+
</env:Envelope>
|
|
22
|
+
xml
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "celsius/primo/soap_api/searcher/search_brief"
|
|
2
|
+
require "celsius/transformation"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchRequestTransformation < Celsius::Transformation
|
|
5
|
+
require_directory "#{File.dirname(__FILE__)}/search_request_transformation"
|
|
6
|
+
|
|
7
|
+
sequence [
|
|
8
|
+
SetupTarget,
|
|
9
|
+
SetupInnerSearchRequest,
|
|
10
|
+
[
|
|
11
|
+
[
|
|
12
|
+
ProcessMatchQueries,
|
|
13
|
+
ProcessQueryStringQueries,
|
|
14
|
+
ProcessRangeQueries,
|
|
15
|
+
ProcessIdsQueries,
|
|
16
|
+
SetStartIndex,
|
|
17
|
+
SetBulkSize,
|
|
18
|
+
SetLanguages,
|
|
19
|
+
AddSortByList,
|
|
20
|
+
SetLocations
|
|
21
|
+
],
|
|
22
|
+
SetInstitution
|
|
23
|
+
],
|
|
24
|
+
EmbedInnerSearchRequest,
|
|
25
|
+
SerializeTargetAsXml
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
attr_accessor :languages
|
|
29
|
+
attr_accessor :locations
|
|
30
|
+
attr_accessor :institution
|
|
31
|
+
attr_accessor :inner_search_request
|
|
32
|
+
|
|
33
|
+
def initialize(options = {})
|
|
34
|
+
@languages = options[:languages]
|
|
35
|
+
@locations = options[:locations]
|
|
36
|
+
@institution = options[:institution]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def index_field_mapping(index_field)
|
|
40
|
+
case index_field
|
|
41
|
+
when "_all" then "any"
|
|
42
|
+
when "created" then "cdate"
|
|
43
|
+
when "identifier" then "any"
|
|
44
|
+
when "language" then "lang"
|
|
45
|
+
when "subject" then "sub"
|
|
46
|
+
else index_field
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def sort_field_mapping(sort_field)
|
|
51
|
+
case sort_field
|
|
52
|
+
when "_score" then "relevance"
|
|
53
|
+
when "created" then "scdate"
|
|
54
|
+
when "creator" then "screator"
|
|
55
|
+
when "title" then "stitle"
|
|
56
|
+
else sort_field
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
AddMissingFacets < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Sometimes, requested facets do not show up in search result, so we have to (re)add them
|
|
9
|
+
#
|
|
10
|
+
def call
|
|
11
|
+
if match_queries = Celsius::Hash.deep_find_key(search_request, :match)
|
|
12
|
+
binding.pry
|
|
13
|
+
raise "unimplemented!"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
private
|
|
19
|
+
#
|
|
20
|
+
=begin
|
|
21
|
+
# handle primo bug where requested facets don't show up in search response
|
|
22
|
+
process "//match", source: -> { @search_request} do |match, target|
|
|
23
|
+
if (target_facet_name = match.nodes.first.value).start_with?("facet_")
|
|
24
|
+
target_facet_value = match.nodes.first.text
|
|
25
|
+
target_facet_count = find_all(@search_brief_return, "SEGMENTS/JAGROOT/RESULT/DOCSET/DOC").length
|
|
26
|
+
|
|
27
|
+
# case 1 - there is no facet at all
|
|
28
|
+
unless find(target, "facets/#{target_facet_name}")
|
|
29
|
+
find(target, "facets") << element(target_facet_name) do |target_facet|
|
|
30
|
+
target_facet << element("_type", text: "terms")
|
|
31
|
+
target_facet << array("terms")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# case 2 - there is a facet, but the requested facet is not included
|
|
36
|
+
unless find_all(target, "facets/#{target_facet_name}/terms/terms/term").map(&:text).include?(target_facet_value)
|
|
37
|
+
array(find(target, "facets/#{target_facet_name}/terms")) do |term|
|
|
38
|
+
term << element("term", text: target_facet_value)
|
|
39
|
+
term << element("count", text: target_facet_count.to_s, type: "integer")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
=end
|
|
45
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
ParseInnerSearchBriefReturn < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
remove_namespaces!(source)
|
|
9
|
+
|
|
10
|
+
string_encoded_search_brief_return =
|
|
11
|
+
Ox.parse(source).locate("Envelope/Body/searchBriefResponse/searchBriefReturn").first
|
|
12
|
+
|
|
13
|
+
transformation.search_brief_return =
|
|
14
|
+
Ox.parse remove_namespaces!(string_encoded_search_brief_return.text)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
private
|
|
19
|
+
#
|
|
20
|
+
def remove_namespaces!(xml)
|
|
21
|
+
xml.gsub!(/<(\/?)\w+:(\w+)/, "<\\1\\2")
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/process_facets.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
ProcessFacets < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
if source_facets = search_brief_return.locate("JAGROOT/RESULT/FACETLIST/FACET")
|
|
9
|
+
source_facets.each do |source_facet|
|
|
10
|
+
target["facets"]["facet_#{source_facet["NAME"]}"] = target_facet(source_facet)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
private
|
|
17
|
+
#
|
|
18
|
+
def target_facet(source_facet)
|
|
19
|
+
{
|
|
20
|
+
"_type" => "terms",
|
|
21
|
+
"terms" => source_facet.locate("FACET_VALUES").map do |source_facet_value|
|
|
22
|
+
{
|
|
23
|
+
"term" => source_facet_value["KEY"].force_encoding("utf-8"),
|
|
24
|
+
"count" => source_facet_value["VALUE"].to_i
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
ProcessRecords < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
add_records!(transformation.target).each do |record|
|
|
9
|
+
[
|
|
10
|
+
{ "_source/control/recordid" => "_id" },
|
|
11
|
+
{ "_source/display/creator" => "creator" },
|
|
12
|
+
{ "_source/display/creationdate" => "created" },
|
|
13
|
+
{ "_source/display/description" => "description" },
|
|
14
|
+
{ "_source/display/edition" => "edition" },
|
|
15
|
+
{ "_source/display/format" => "format" },
|
|
16
|
+
{ "_source/control/ilsapiid" => "identifier" },
|
|
17
|
+
{ "_source/control/recordid" => "identifier" },
|
|
18
|
+
{ "_source/search/isbn" => "isbn" },
|
|
19
|
+
{ "_source/search/issn" => "issn" },
|
|
20
|
+
{ "_source/display/language" => "language" },
|
|
21
|
+
{ "_source/display/title" => "title" },
|
|
22
|
+
{ "_source/display/publisher" => "publisher" },
|
|
23
|
+
{ "_source/display/subject" => "subject" }
|
|
24
|
+
].each do |mapping|
|
|
25
|
+
map_record_field!(record, mapping.keys.first, mapping.values.first)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
add_place_of_publication!(record)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
private
|
|
34
|
+
#
|
|
35
|
+
def add_place_of_publication!(record)
|
|
36
|
+
if record["publisher"]
|
|
37
|
+
record["publisher"].match(/(\A[^:]*):(.*)/) do |match|
|
|
38
|
+
place_of_publication, publisher = match.captures.map(&:strip)
|
|
39
|
+
|
|
40
|
+
record["placeOfPublication"] = place_of_publication
|
|
41
|
+
record["publisher"].replace(publisher)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def add_records!(target)
|
|
47
|
+
(search_brief_return.locate("JAGROOT/RESULT/DOCSET/DOC") || []).each do |source_record|
|
|
48
|
+
target["hits"]["hits"].push({
|
|
49
|
+
"_type" => "record",
|
|
50
|
+
"_source" => source_record.locate("PrimoNMBib/record/?").inject({}) do |_source, section|
|
|
51
|
+
_source.merge! section.value => transformation.hash_from_ox_element(section)
|
|
52
|
+
end
|
|
53
|
+
})
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
target["hits"]["hits"] # for chaining
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def map_record_field!(record, source_path, target_path)
|
|
60
|
+
source_value = resolve_path(record, source_path)
|
|
61
|
+
target = resolve_path(record, target_path, -2)
|
|
62
|
+
target_key = target_path.split("/").last
|
|
63
|
+
|
|
64
|
+
if target[target_key]
|
|
65
|
+
target[target_key] = [target[target_key]]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
if target[target_key].is_a?(Array)
|
|
69
|
+
(target[target_key] << source_value).flatten(1)
|
|
70
|
+
else
|
|
71
|
+
target[target_key] = source_value
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def resolve_path(object, path, level = -1)
|
|
76
|
+
path.split("/").slice(0..level).inject(object) do |_object, key|
|
|
77
|
+
_object[key] unless _object.nil?
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
RemoveBogusCreationdateFacets < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Sometimes, there are creationdate facets entries 1 and 500, which are bogus
|
|
9
|
+
#
|
|
10
|
+
def call
|
|
11
|
+
((target["facets"]["facet_creationdate"] || {})["terms"] || []).reject! do |element|
|
|
12
|
+
element["term"] == "1" || element["term"] == "500"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
SelectOnlyRequestedFacets < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
if requested_facets_names = Celsius::Hash.deep_find_key(search_request, [:facets, :field])
|
|
9
|
+
target["facets"].select! do |target_facet_name, _|
|
|
10
|
+
requested_facets_names.include?(target_facet_name)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/set_total_hits.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
SetTotalHits < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
if docset = (search_brief_return.locate("JAGROOT/RESULT/DOCSET") || []).first
|
|
9
|
+
target["hits"]["total"] = docset[:TOTALHITS].to_i
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
SetupTargetSkeleton < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
transformation.target = {
|
|
9
|
+
"took" => nil,
|
|
10
|
+
"hits" => {
|
|
11
|
+
"hits" => [],
|
|
12
|
+
"total" => 0
|
|
13
|
+
},
|
|
14
|
+
"facets" => {}
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "celsius/transformation/step"
|
|
2
|
+
require "ox"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
|
|
5
|
+
SortFacetsBySearchRequest < Celsius::Transformation::Step
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
if requested_facets_names = Celsius::Hash.deep_find_key(search_request, [:facets, :field])
|
|
9
|
+
original_target_facets = target["facets"]
|
|
10
|
+
|
|
11
|
+
# ruby has a order-preserving hash, so sorting means recreating with the desired order
|
|
12
|
+
target["facets"] = {}.tap do |target_facets|
|
|
13
|
+
requested_facets_names.each do |facet_name|
|
|
14
|
+
if original_target_facet_value = original_target_facets[facet_name]
|
|
15
|
+
target_facets[facet_name] = original_target_facet_value
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "celsius/primo/soap_api/searcher/search_brief"
|
|
2
|
+
require "celsius/transformation"
|
|
3
|
+
|
|
4
|
+
class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation < Celsius::Transformation
|
|
5
|
+
require_directory "#{File.dirname(__FILE__)}/search_result_transformation"
|
|
6
|
+
|
|
7
|
+
sequence [
|
|
8
|
+
ParseInnerSearchBriefReturn,
|
|
9
|
+
SetupTargetSkeleton,
|
|
10
|
+
SetTotalHits,
|
|
11
|
+
[ # facets
|
|
12
|
+
ProcessFacets,
|
|
13
|
+
AddMissingFacets,
|
|
14
|
+
RemoveBogusCreationdateFacets,
|
|
15
|
+
SelectOnlyRequestedFacets,
|
|
16
|
+
SortFacetsBySearchRequest
|
|
17
|
+
],
|
|
18
|
+
ProcessRecords
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
attr_accessor :search_brief_return
|
|
22
|
+
attr_accessor :search_request
|
|
23
|
+
|
|
24
|
+
def initialize(options = {})
|
|
25
|
+
@search_request = options[:search_request]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def hash_from_ox_element(ox_element)
|
|
29
|
+
OxHelpers.hash_from_ox_element(ox_element)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module OxHelpers
|
|
33
|
+
def self.hash_from_ox_element(ox_element)
|
|
34
|
+
if string_element?(ox_element)
|
|
35
|
+
ox_element.first.force_encoding("utf-8")
|
|
36
|
+
else
|
|
37
|
+
ox_element.nodes.inject({}) do |hash, node|
|
|
38
|
+
key = node.value
|
|
39
|
+
|
|
40
|
+
if hash[key].is_a?(String)
|
|
41
|
+
hash[key] = [hash[key]]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if hash[key].is_a?(Array)
|
|
45
|
+
hash[key] << hash_from_ox_element(node.nodes)
|
|
46
|
+
else
|
|
47
|
+
hash[key] = hash_from_ox_element(node.nodes)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
hash
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.string_element?(ox_element)
|
|
56
|
+
ox_element.is_a?(Array) && ox_element.length == 1 && ox_element.first.is_a?(String)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|