Skip to content

Commit

Permalink
Merge pull request #396 from datacite/feature_metric_from_rest
Browse files Browse the repository at this point in the history
reduce number of ES queries to obtain metrics in DOI list for researcher profile
  • Loading branch information
kjgarza authored Feb 2, 2020
2 parents 8111a32 + 88c2d5e commit ce3fc0c
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 88 deletions.
58 changes: 51 additions & 7 deletions app/controllers/concerns/metrics_helper.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
require "pp"
module MetricsHelper
extend ActiveSupport::Concern
include Helpable

class_methods do
def doi_citations(doi)
EventsQuery.new.doi_citations(doi)
included do
def get_metrics_array(dois)
citations = EventsQuery.new.citations(dois)
usage = EventsQuery.new.views_and_downloads(dois)
merge_array_hashes(citations, usage)
end

def doi_views(doi)
EventsQuery.new.doi_views(doi)
def get_person_metrics(orcid)
dois = get_person_dois(orcid).join(",")
usage = EventsQuery.new.views_and_downloads(dois)
{
citations: EventsQuery.new.citations(dois).sum { |h| h[:citations] },
views: usage.sum { |h| h[:views] },
downloads: usage.sum { |h| h[:downloads] },
}
end

def doi_downloads(doi)
EventsQuery.new.doi_downloads(doi)
def get_person_dois(orcid)
Event.query(nil, page: { size: 500 }, obj_id: https_to_http(orcid)).results.to_a.map do |e|
doi_from_url(e.subj_id)
end
end

def https_to_http(url)
orcid = orcid_from_url(url)
return nil if orcid.blank?

"https://orcid.org/#{orcid}"
end

def mix_in_metrics_array(metadata_array_objects, metrics_array_hashes)
return [] if metadata_array_objects.empty?

metadata_array_objects.map do |metadata|
metadata_hash = metadata.to_hash
metrics = metrics_array_hashes.select { |hash| hash[:id] == metadata_hash["_source"]["uid"] }.first
Hashie::Mash.new(metadata_hash)._source.shallow_update(metrics)
end
end

def mix_in_metrics(metadata, metrics)
metadata_hash = metadata.attributes
metrics[:doi] = metrics.delete :id
metrics[:uid] = metrics[:doi]
metrics[:doi] = metrics[:doi].upcase
metadata_hash.merge!(metrics)
Hashie::Mash.new(metadata_hash)
end
end

# class_methods do
# # def mix_in_metrics(doi, metrics_array_hashes)
# # metrics_array_hashes.select { |hash| hash[:id] == doi }.first
# # end
# end
end
21 changes: 20 additions & 1 deletion app/controllers/dois_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
class DoisController < ApplicationController
include ActionController::MimeResponds
include Crosscitable
include MetricsHelper # mixes in your helper method as class method


prepend_before_action :authenticate_user!
before_action :set_include, only: [:index, :show, :create, :update]
Expand Down Expand Up @@ -198,6 +200,13 @@ def index
}
logger.warn method: "GET", path: "/dois", message: "AggregationsLinkChecks /dois", duration: bm

if params[:mix_in] == "metrics"
dois_names = results.map { |result| result.dig(:_source, :doi) }.join(',')
metrics_array = get_metrics_array(dois_names)
results = mix_in_metrics_array(results, metrics_array)
end

person_metrics = params[:mix_in] == "metrics" ? get_person_metrics(params[:user_id]) : {}

respond_to do |format|
format.json do
Expand Down Expand Up @@ -225,6 +234,9 @@ def index
"linkChecksDcIdentifier" => link_checks_dc_identifier,
"linkChecksCitationDoi" => link_checks_citation_doi,
subjects: subjects,
citations: person_metrics[:citations],
views: person_metrics[:views],
downloads: person_metrics[:downloads],
}.compact

options[:links] = {
Expand All @@ -247,6 +259,7 @@ def index
detail: params[:detail],
events: params[:events],
mix_in: params[:mix_in],
metrics: metrics_array,
affiliation: params[:affiliation],
is_collection: options[:is_collection]
}
Expand Down Expand Up @@ -286,6 +299,11 @@ def show
doi = Doi.where(doi: params[:id]).first
fail ActiveRecord::RecordNotFound if not_allowed_by_doi_and_user(doi: doi, user: current_user)

if params[:mix_in] == "metrics"
metrics_array = get_metrics_array(doi.uid) || []
doi = mix_in_metrics(doi, metrics_array.first)
end

respond_to do |format|
format.json do
options = {}
Expand All @@ -295,7 +313,8 @@ def show
current_ability: current_ability,
events: params[:events],
detail: true,
affiliation: params[:affiliation]
mix_in: params[:mix_in],
affiliation: params[:affiliation],
}

render json: DoiSerializer.new(doi, options).serialized_json, status: :ok
Expand Down
19 changes: 8 additions & 11 deletions app/graphql/types/person_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,26 @@ def creative_works(**_args)
end

def citation_count(**_args)
dois = Event.query(nil, page: { size: 500 }, obj_id: https_to_http(object[:id])).results.to_a.map do |e|
doi_from_url(e.subj_id)
end
EventsQuery.new.citations(dois.join(",")).sum { |h| h[:count] }
EventsQuery.new.citations(get_dois.join(",")).sum { |h| h[:citations] }
end

def view_count(**_args)
dois = Event.query(nil, page: { size: 500 }, obj_id: https_to_http(object[:id])).results.to_a.map do |e|
doi_from_url(e.subj_id)
end
EventsQuery.new.views(dois.join(",")).sum { |h| h[:count] }
EventsQuery.new.views(get_dois.join(",")).sum { |h| h[:views] }
end

def download_count(**_args)
dois = Event.query(nil, page: { size: 500 }, obj_id: https_to_http(object[:id])).results.to_a.map do |e|
EventsQuery.new.downloads(get_dois.join(",")).sum { |h| h[:downloads] }
end

def get_dois
Event.query(nil, page: { size: 500 }, obj_id: https_to_http(object[:id])).results.to_a.map do |e|
doi_from_url(e.subj_id)
end
EventsQuery.new.downloads(dois.join(",")).sum { |h| h[:count] }
end

def https_to_http(url)
orcid = orcid_from_url(url)
return nil unless orcid.present?
return nil if orcid.blank?

"https://orcid.org/#{orcid}"
end
Expand Down
11 changes: 11 additions & 0 deletions app/models/concerns/helpable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ def register_url
response
end

def merge_array_hashes(first_array, second_array)
return first_array if second_array.blank?
return second_array if first_array.blank?

total = first_array | second_array
total.group_by { |hash| hash[:id] }.map do |key, value|
metrics = value.reduce(&:merge)
{ id: key }.merge(metrics)
end
end

def get_url
url = "#{ENV['HANDLE_URL']}/api/handles/#{doi}?index=1"
response = Maremma.get(url, ssl_self_signed: true, timeout: 10)
Expand Down
8 changes: 8 additions & 0 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,14 @@ def self.usage_count_aggregation
}
end

def self.multiple_usage_count_aggregation
{
usage: {
terms: { field: "obj_id", size: 50, min_doc_count: 1 } , aggs: { relation_types: { terms: { field: "relation_type_id", size: 50, min_doc_count: 1 }, aggs: { "total_by_type" => { sum: { field: "total" } } } } }
}
}
end

def self.yearly_histogram_aggregation
sum_year_distribution = {
sum_bucket: {
Expand Down
Loading

0 comments on commit ce3fc0c

Please sign in to comment.