Skip to content

Commit

Permalink
Merge pull request #349 from datacite/feature_refenreces_citaitons
Browse files Browse the repository at this point in the history
Feature references, citations, relations links
  • Loading branch information
kjgarza authored Nov 1, 2019
2 parents 50a6ff3 + 34708c5 commit 30a9ab1
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 65 deletions.
2 changes: 1 addition & 1 deletion app/controllers/concerns/facetable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def facet_citations_by_dois(arr)
arr.map do |hsh|
{ "id" => hsh["key"],
"title" => hsh["key"],
"citations" => hsh.dig("unique_citations", "value")}
"count" => hsh.dig("total", "value")}
end
end

Expand Down
8 changes: 6 additions & 2 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,10 @@ def index
dois = total.positive? && aggregations.blank? || aggregations.include?("query_aggregations") ? facet_by_dois(response.response.aggregations.dois.buckets) : nil
dois_usage = total.positive? && aggregations.blank? || aggregations.include?("query_aggregations") ? facet_by_dois(response.response.aggregations.dois_usage.dois.buckets) : nil
dois_citations = total.positive? && aggregations.blank? || aggregations.include?("query_aggregations") ? facet_citations_by_year_v1(response.response.aggregations.dois_citations) : nil
citations_histogram = total.positive? && aggregations.include?("metrics_aggregations") ? facet_citations_by_year(response.response.aggregations.citations_histogram) : nil
citations = total.positive? && aggregations.include?("metrics_aggregations") ? facet_citations_by_dois(response.response.aggregations.citations.dois.buckets) : nil
citations_histogram = total.positive? && params[:doi].present? && aggregations.include?("citations_aggregations") ? facet_citations_by_year(response.response.aggregations.citations_histogram) : nil
citations = total.positive? && params[:doi].present? && aggregations.include?("citations_aggregations") ? facet_citations_by_dois(response.response.aggregations.citations.dois.buckets) : nil
references = total.positive? && params[:doi].present? && aggregations.include?("citations_aggregations") ? facet_citations_by_dois(response.response.aggregations.references.dois.buckets) : nil
relations = total.positive? && params[:doi].present? && aggregations.include?("citations_aggregations") ? facet_citations_by_dois(response.response.aggregations.relations.dois.buckets) : nil
views_histogram = total.positive? && aggregations.include?("metrics_aggregations") ? facet_counts_by_year_month(response.response.aggregations.views_histogram) : nil
downloads_histogram = total.positive? && aggregations.include?("metrics_aggregations") ? facet_counts_by_year_month(response.response.aggregations.downloads_histogram) : nil
views = total.positive? && aggregations.include?("metrics_aggregations") ? facet_by_source(response.response.aggregations.views.dois.buckets) : nil
Expand All @@ -153,6 +155,8 @@ def index
"doisCitations": dois_citations,
"citationsHistogram": citations_histogram,
"uniqueCitations": citations,
"references": references,
"relations": relations,
"uniqueNodes": {
"objCount": unique_obj_count,
"subjCount": unique_subj_count
Expand Down
45 changes: 43 additions & 2 deletions app/graphql/types/metric_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ module MetricInterface
field :view_count, Integer, null: true, description: "The count of DOI views according to the COUNTER code of Practice"
field :download_count, Integer, null: true, description: "The count of DOI dowloands according to the COUNTER code of Practice"
field :citation_count, Integer, null: true, description: "The count of DOI events that represents citations"

field :citations_list, [String], null: true, description: "List of DOIS citing a given DOI"
field :referenceslist, [String], null: true, description: "List of DOIS that a given DOI references to"
field :relations_list, [String], null: true, description: "List of DOIS relations a given DOI has"

def aggregation_results(**args)
Event.query(nil, doi: doi_from_url(args[:id]), "page[size]": 0, aggregations: "metrics_aggregations", source_id: args[:source_id] || nil).response.aggregations
end
Expand All @@ -22,7 +25,45 @@ def download_count
end

def citation_count
meta = aggregation_results(id: object.identifier).citations.dois.buckets
meta = citations_aggs
meta.first.fetch("unique_citations", {}).fetch("value", nil) if meta.any?
end

def references_count
meta = references_aggs
meta.first.fetch("references", {}).fetch("value", nil) if meta.any?
end

def relations_count
meta = relations_aggs
meta.first.fetch("relations", {}).fetch("value", nil) if meta.any?
end

def references_list
references_aggs.map { |item| item[:key]}
end

def relations_list
relations_aggs.map { |item| item[:key]}
end

def citations_list
citations_aggs.map { |item| item[:key]}
# citations_aggs.map do |item|
# puts item[:key]
# puts Doi.find_by_id(item[:key]).results.first
# end
end

def citations_aggs
aggregation_results(id: object.identifier).citations.dois.buckets
end

def references_aggs
aggregation_results(id: object.identifier).references.dois.buckets
end

def relations_aggs
aggregation_results(id: object.identifier).relations.dois.buckets
end
end
8 changes: 5 additions & 3 deletions app/models/concerns/indexable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,20 @@ def find_by_id_list(ids, options={})
})
end

def get_aggregations_hash(aggregations = "")
def get_aggregations_hash(options={})
aggregations = options[:aggregations] || ""
return send(:query_aggregations) if aggregations.blank?
aggs = {}
aggregations.split(",").each do |agg|
agg = :query_aggregations if agg.blank? || !respond_to?(agg)
aggs.merge! send(agg)
doi = options[:doi].present? ? options[:doi].downcase.split(",").first : nil
aggs.merge! send(agg,doi)
end
aggs
end

def query(query, options={})
aggregations = options[:totals_agg] == true ? totals_aggregations : get_aggregations_hash(options[:aggregations])
aggregations = options[:totals_agg] == true ? totals_aggregations : get_aggregations_hash(options)
options[:page] ||= {}
options[:page][:number] ||= 1
options[:page][:size] ||= 25
Expand Down
97 changes: 72 additions & 25 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,37 @@ class Event < ActiveRecord::Base

INCLUDED_RELATION_TYPES = [
"cites", "is-cited-by",
"is-supplement-to", "is-supplemented-by",
"references", "is-referenced-by"
]

ACTIVE_RELATION_TYPES = [
"cites",
"is-supplement-to",
"references"
]

PASSIVE_RELATION_TYPES = [
"is-cited-by",
"is-supplemented-by",
"is-referenced-by"
]


RELATIONS_RELATION_TYPES = [
"compiles", "is-compiled-by",
"documents", "is-documented-by",
"has-metadata", "is-metadata-for",
"is-supplement-to", "is-supplemented-by",
"is-derived-from", "is-source-of",
"references", "is-referenced-by",
"reviews", "is-reviewed-by",
"requires", "is-required-by",
"continues", "is-coutinued-by",
"has-version", "is-version-of",
"has-part", "is-part-of",
"is-variant-from-of", "is-original-form-of",
"is-identical-to", "obsoletes",
"is-obsolete-by",
"is-new-version-of", "is-previous-version-of",
"describes", "is-described-by"
]

Expand Down Expand Up @@ -183,7 +206,7 @@ def self.query_fields
['subj_id^10', 'obj_id^10', 'subj.name^5', 'subj.author^5', 'subj.periodical^5', 'subj.publisher^5', 'obj.name^5', 'obj.author^5', 'obj.periodical^5', 'obj.publisher^5', '_all']
end

def self.query_aggregations
def self.query_aggregations(doi=nil)
sum_distribution = {
sum_bucket: {
buckets_path: "year_months>total_by_year_month"
Expand Down Expand Up @@ -220,35 +243,18 @@ def self.query_aggregations
}
end

def self.metrics_aggregations
def self.metrics_aggregations(doi=nil)
sum_distribution = {
sum_bucket: {
buckets_path: "year_months>total_by_year_month"
}
}
sum_year_distribution = {
sum_bucket: {
buckets_path: "years>total_by_year"
}
}


views_filter = {script: {script: "#{VIEWS_RELATION_TYPES}.contains(doc['relation_type_id'].value) && doc['source_id'].value == 'datacite-usage' && doc['occurred_at'].value.getMillis() >= doc['obj.datePublished'].value.getMillis() && doc['occurred_at'].value.getMillis() < new Date().getTime()"}}

downloads_filter = {script: {script: "#{DOWNLOADS_RELATION_TYPES}.contains(doc['relation_type_id'].value) && doc['source_id'].value == 'datacite-usage' && doc['occurred_at'].value.getMillis() >= doc['obj.datePublished'].value.getMillis() && doc['occurred_at'].value.getMillis() < new Date().getTime()"} }

{
citations_histogram: {
filter: {script: {script: "#{INCLUDED_RELATION_TYPES}.contains(doc['relation_type_id'].value)"}
},
aggs: { years: { histogram: { field: 'citation_year', interval: 1 , min_doc_count: 1 }, aggs: { "total_by_year" => { sum: { field: 'total' }}}},"sum_distribution"=>sum_year_distribution}
},
citations: {
filter: {script: {script: "#{INCLUDED_RELATION_TYPES}.contains(doc['relation_type_id'].value)"}
},
aggs: { dois: {
terms: { field: 'doi', size: 100, min_doc_count: 1 }, aggs: { unique_citations: { cardinality: { field: 'citation_id' }}}
}}
},
{
views: {
filter: views_filter,
aggs: { dois: {
Expand All @@ -273,7 +279,48 @@ def self.metrics_aggregations
year_months: { date_histogram: { field: 'occurred_at', interval: 'month', min_doc_count: 1 }, aggs: { "total_by_year_month" => { sum: { field: 'total' } } } }, "sum_distribution" => sum_distribution
}
}
}
}

end

def self.citations_aggregations(doi)
doi = Event.new.normalize_doi(doi) if doi.present?

sum_year_distribution = {
sum_bucket: {
buckets_path: "years>total_by_year"
}
}

citations_filter = {script: {script: "(#{PASSIVE_RELATION_TYPES}.contains(doc['relation_type_id'].value) && '#{doi}' == doc['subj_id'].value) || (#{ACTIVE_RELATION_TYPES}.contains(doc['relation_type_id'].value) && '#{doi}' == doc['obj_id'].value)"}}

references_filter = {script: {script: "(#{PASSIVE_RELATION_TYPES}.contains(doc['relation_type_id'].value) && '#{doi}' == doc['obj_id'].value) || (#{ACTIVE_RELATION_TYPES}.contains(doc['relation_type_id'].value) && '#{doi}' == doc['subj_id'].value)"}}

{
citations_histogram: {
filter: citations_filter,
aggs: { years: { histogram: { field: 'citation_year', interval: 1 , min_doc_count: 1 }, aggs: { "total_by_year" => { sum: { field: 'total' }}}},"sum_distribution"=>sum_year_distribution}
},
citations: {
filter: citations_filter,
aggs: { dois: {
terms: { field: 'doi', size: 100, min_doc_count: 1 }, aggs: { total: { cardinality: { field: 'citation_id' }}}
}}
},
references: {
filter: references_filter,
aggs: { dois: {
terms: { field: 'doi', size: 100, min_doc_count: 1 }, aggs: { total: { cardinality: { field: 'citation_id' }}}
}}
},
relations: {
filter: {script: {script: "#{RELATIONS_RELATION_TYPES}.contains(doc['relation_type_id'].value)"}
},
aggs: { dois: {
terms: { field: 'doi', size: 100, min_doc_count: 1 }, aggs: { total: { cardinality: { field: 'citation_id' }}}
}}
}
}
end

def self.advanced_aggregations
Expand Down Expand Up @@ -608,7 +655,7 @@ def obj_cache_key
end

def citation_year
"" unless INCLUDED_RELATION_TYPES.include?(relation_type_id)
"" unless (INCLUDED_RELATION_TYPES+RELATIONS_RELATION_TYPES).include?(relation_type_id)
subj_publication = subj['date_published'] || (date_published(subj_id) || year_month)
obj_publication = obj['date_published'] || (date_published(obj_id) || year_month)
[subj_publication[0..3].to_i, obj_publication[0..3].to_i].max
Expand Down
12 changes: 6 additions & 6 deletions spec/concerns/indexable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@

context "aggregations" do
it 'returns query_aggregation when filters aggregation with empty' do
aggregations = Doi.get_aggregations_hash("")
aggregations = Doi.get_aggregations_hash({aggregations:""})
expect(aggregations[:resource_types]).not_to be_nil
expect(aggregations[:states]).not_to be_nil
expect(aggregations[:created]).not_to be_nil
expect(aggregations[:schema_versions]).not_to be_nil
end

it 'returns multiple aggregations when filters aggregations with multiple' do
aggregations = Doi.get_aggregations_hash("query_aggregations,metrics_aggregations")
aggregations = Doi.get_aggregations_hash({aggregations:""})
expect(aggregations[:resource_types]).not_to be_nil
expect(aggregations[:states]).not_to be_nil
expect(aggregations[:created]).not_to be_nil
Expand All @@ -154,7 +154,7 @@

context "aggregations" do
it 'returns query_aggregation when filters aggregation with empty' do
aggregations = Event.get_aggregations_hash("")
aggregations = Event.get_aggregations_hash({aggregations:""})
expect(aggregations[:sources]).not_to be_nil
expect(aggregations[:prefixes]).not_to be_nil
expect(aggregations[:citation_types]).not_to be_nil
Expand All @@ -167,7 +167,7 @@
end

it 'returns multiple aggregations when filters aggregations with multiple' do
aggregations = Event.get_aggregations_hash("query_aggregations,metrics_aggregations")
aggregations = Event.get_aggregations_hash({aggregations:"query_aggregations,metrics_aggregations"})
expect(aggregations[:sources]).not_to be_nil
expect(aggregations[:prefixes]).not_to be_nil
expect(aggregations[:citation_types]).not_to be_nil
Expand All @@ -176,8 +176,8 @@
expect(aggregations[:pairings]).not_to be_nil
expect(aggregations[:dois]).not_to be_nil
expect(aggregations[:dois_usage]).not_to be_nil
expect(aggregations[:citations_histogram]).not_to be_nil
expect(aggregations[:citations]).not_to be_nil
expect(aggregations[:citations_histogram]).to be_nil
expect(aggregations[:citations]).to be_nil
end
end
end
Expand Down
Loading

0 comments on commit 30a9ab1

Please sign in to comment.