Skip to content

Commit

Permalink
ugly but it works
Browse files Browse the repository at this point in the history
Needs big refactor… DO NOT MERGE
  • Loading branch information
elrayle committed Nov 29, 2017
1 parent fdd4bd9 commit c45c079
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 24 deletions.
13 changes: 13 additions & 0 deletions lib/qa/authorities/linked_data/config/search_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ def results_sort_predicate
Config.predicate_uri(results, :sort_predicate)
end

# Does this authority configuration select results based on a predicate existing?
# @return [True|False] true if sorting of search results is supported; otherwise, false
def select_results_based_on_predicate?
return true unless results_selector_predicate.nil? || !results_selector_predicate.size.positive?
false
end

# Return predicate that is used to select a subject URI as a matching result term
# @return [String] the configured predicate to use to select a subject URI as a matching result term
def results_selector_predicate
Config.predicate_uri(results, :selector_predicate)
end

# Does this authority configuration support additional context in search results?
# @return [True|False] true if additional context in search results is supported; otherwise, false
def supports_context?
Expand Down
14 changes: 14 additions & 0 deletions lib/qa/authorities/linked_data/rdf_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,20 @@ def extract_preds(graph, preds)
end
end

def extract_preds_for_uri(graph, preds, uri)
RDF::Query.execute(graph) do
preds[:required].each do |key, pred|
pattern([uri, pred, key])
end
preds[:optional].each do |key, pred|
pattern([uri, pred, key], optional: true)
end
preds[:context].each do |key, pred|
pattern([uri, pred, key], optional: true)
end if preds.key? :context
end
end

def sort_string_by_language(str_literals)
return str_literals if str_literals.nil? || str_literals.size <= 0
str_literals.sort! { |a, b| a.language <=> b.language } if str_literals.first.respond_to? :language
Expand Down
103 changes: 79 additions & 24 deletions lib/qa/authorities/linked_data/search_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def initialize(search_config)
end

attr_reader :search_config
attr_reader :graph

delegate :subauthority?, :supports_sort?, to: :search_config

Expand All @@ -29,22 +30,24 @@ def search(query, language: nil, replacements: {}, subauth: nil)
language ||= search_config.language
url = search_config.url_with_replacements(query, subauth, replacements)
Rails.logger.info "QA Linked Data search url: #{url}"
graph = get_linked_data(url)
parse_search_authority_response(graph, language)
@graph = get_linked_data(url)
parse_search_authority_response(language)
end

private

def parse_search_authority_response(graph, language)
graph = filter_language(graph, language) unless language.nil?
results = extract_preds(graph, preds_for_search)
consolidated_results = consolidate_search_results(results)
def parse_search_authority_response(language)
@graph = filter_language(graph, language) unless language.nil?
results = extract_preds(graph, preds_for_search(include_sort: true, include_context: true))
consolidated_results = consolidate_search_results(results, include_context: true)
json_results = convert_search_to_json(consolidated_results)
sort_search_results(json_results)
end

def preds_for_search
{ required: required_search_preds, optional: optional_search_preds, context: context_search_preds }
def preds_for_search(include_sort: true, include_context: false)
preds = { required: required_search_preds, optional: optional_search_preds(include_sort) }
preds[:context] = context_search_preds if include_context
preds
end

def required_search_preds
Expand All @@ -53,51 +56,95 @@ def required_search_preds
{ label: label_pred_uri }
end

def optional_search_preds
def optional_search_preds(include_sort)
preds = {}
preds[:altlabel] = search_config.results_altlabel_predicate unless search_config.results_altlabel_predicate.nil?
preds[:id] = search_config.results_id_predicate unless search_config.results_id_predicate.nil?
preds[:sort] = search_config.results_sort_predicate unless search_config.results_sort_predicate.nil?
preds[:sort] = search_config.results_sort_predicate unless search_config.results_sort_predicate.nil? || !include_sort
preds[:selector] = search_config.results_selector_predicate if search_config.select_results_based_on_predicate?
preds
end

def context_search_preds
search_config.results_context || {}
end

def consolidate_search_results(results)
def consolidate_search_results(results, include_context: false, process_all: false, default_uri: nil)
return {} if results.nil? || !results.count.positive?
consolidated_results = convert_statements_to_hash(results, include_context, process_all, default_uri)
consolidated_results = sort_multiple_result_values(consolidated_results)
consolidated_results = fill_in_secondary_context_values(consolidated_results) if include_context
consolidated_results
end

def convert_statements_to_hash(results, include_context, process_all, default_uri)
consolidated_results = {}
return consolidated_results if results.nil? || !results.count.positive?
results.each do |statement|
stmt_hash = statement.to_h
uri = stmt_hash[:uri].to_s
uri = default_uri unless uri.present?

consolidated_hash = init_consolidated_hash(consolidated_results, uri, stmt_hash[:id].to_s)
next unless process_all || result_statement?(stmt_hash)

consolidated_hash[:label] = object_value(stmt_hash, consolidated_hash, :label, false)
consolidated_hash[:altlabel] = object_value(stmt_hash, consolidated_hash, :altlabel, false)
consolidated_hash[:sort] = object_value(stmt_hash, consolidated_hash, :sort, false)

# add context
context_search_preds.each_key do |k|
consolidated_hash[k] = object_value(stmt_hash, consolidated_hash, k, false)
end
consolidated_hash = extract_context_values(stmt_hash, consolidated_hash) if include_context

consolidated_results[uri] = consolidated_hash
end
consolidated_results.each do |res|
consolidated_hash = res[1]
consolidated_hash[:label] = sort_string_by_language consolidated_hash[:label]
consolidated_hash[:altlabel] = sort_string_by_language consolidated_hash[:altlabel]
consolidated_hash[:sort] = sort_string_by_language consolidated_hash[:sort]
consolidated_results
end

def extract_context_values(stmt_hash, consolidated_hash)
current_context = consolidated_hash[:context] || {}
context = {}
context_search_preds.each_key do |k|
context[k] = object_value(stmt_hash, current_context, k, false)
end
consolidated_hash[:context] = context
consolidated_hash
end

def sort_multiple_result_values(consolidated_results)
consolidated_results.each do |uri, predicate_hash|
predicate_hash[:label] = sort_string_by_language predicate_hash[:label]
predicate_hash[:altlabel] = sort_string_by_language predicate_hash[:altlabel]
predicate_hash[:sort] = sort_string_by_language predicate_hash[:sort]
consolidated_results[uri] = predicate_hash
end
consolidated_results
end

# consolidate context
def fill_in_secondary_context_values(consolidated_results)
return consolidated_results unless search_config.supports_context?
consolidated_results.each do |uri, predicate_hash|
context = predicate_hash[:context]
context_search_preds.each_key do |k|
consolidated_hash[k] = sort_string_by_language consolidated_hash[k]
if context[k].first.is_a? RDF::URI
filled_context = {}
context[k].each do |context_uri|
expanded_results = extract_preds_for_uri(graph, preds_for_search(include_context: false, include_sort: false), context_uri)
filled_context.merge!(consolidate_search_results(expanded_results, include_context: false, process_all: true, default_uri: context_uri.to_s))
end
context[k] = filled_context
else
context[k] = sort_string_by_language context[k]
end
end
predicate_hash[:context] = context
consolidated_results[uri] = predicate_hash
end
consolidated_results
end

def result_statement?(stmt_hash)
return true unless search_config.select_results_based_on_predicate?
stmt_hash[:selector].present?
end

def convert_search_to_json(consolidated_results)
json_results = []
consolidated_results.each do |uri, h|
Expand All @@ -111,7 +158,15 @@ def convert_search_to_json(consolidated_results)
def context_json(consolidated_results_hash)
context_json = {}
context_search_preds.each_key do |k|
context_json[k] = consolidated_results_hash[k]
if consolidated_results_hash[:context][k].is_a? Hash
json_value = []
consolidated_results_hash[:context][k].each do |uri, ch|
json_value << { uri: uri, id: ch[:id], label: full_label(ch[:label], ch[:altlabel]) }
end
else
json_value = consolidated_results_hash[:context][k]
end
context_json[k] = json_value
end
context_json
end
Expand Down

0 comments on commit c45c079

Please sign in to comment.