Skip to content

Commit

Permalink
Merge pull request #1049 from datacite/11-30-Add_person_id_to_doi_model
Browse files Browse the repository at this point in the history
Add person_id to doi model
  • Loading branch information
jrhoads authored Dec 6, 2023
2 parents 9dff073 + 9467a6f commit ad5b17c
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 8 deletions.
46 changes: 38 additions & 8 deletions app/models/doi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ def validate_publisher_obj?(doi)
indexes :provider_id, type: :keyword
indexes :consortium_id, type: :keyword
indexes :resource_type_id, type: :keyword
indexes :person_id, type: :keyword
indexes :affiliation_id, type: :keyword
indexes :fair_affiliation_id, type: :keyword
indexes :organization_id, type: :keyword
Expand Down Expand Up @@ -563,6 +564,14 @@ def validate_publisher_obj?(doi)
indexes :fields_of_science, type: :keyword
indexes :fields_of_science_combined, type: :keyword
indexes :fields_of_science_repository, type: :keyword
indexes :related_doi, type: :object, properties: {
client_id: { type: :keyword },
doi: { type: :keyword },
organization_id: { type: :keyword },
person_id: { type: :keyword },
resource_type_id: { type: :keyword },
resource_type_id_and_name: { type: :keyword },
}
end
end

Expand Down Expand Up @@ -1672,6 +1681,10 @@ def consortium_id
client.provider.consortium_id.downcase if client.present? && client.provider.consortium_id.present?
end

def related_dois
Doi::Indexer::RelatedDoiIndexer.new(related_identifiers).as_indexed_json
end

def related_dmp_ids
Array.wrap(related_identifiers).select { |related_identifier|
related_identifier["relatedIdentifierType"] == "DOI"
Expand Down Expand Up @@ -1702,21 +1715,38 @@ def sponsor_contributors
end


def person_id
(Array.wrap(creators) + Array.wrap(contributors)).reduce([]) do |sum, c|
Array.wrap(c.fetch("nameIdentifiers", nil)).each do |name_identifier|
if name_identifier.is_a?(Hash) && name_identifier.fetch("nameIdentifierScheme", nil) == "ORCID" && name_identifier.fetch("nameIdentifier", nil).present?
sum << orcid_as_url(
orcid_from_url(name_identifier.fetch("nameIdentifier", nil))
)
end
end
sum.uniq
end
end

def organization_id
(Array.wrap(creators) + Array.wrap(contributors)).reduce([]) do |sum, c|
Array.wrap(c.fetch("nameIdentifiers", nil)).each do |name_identifier|
sum << ror_from_url(name_identifier.fetch("nameIdentifier", nil)) if name_identifier.is_a?(Hash) && name_identifier.fetch("nameIdentifierScheme", nil) == "ROR" && name_identifier.fetch("nameIdentifier", nil).present?
if name_identifier.is_a?(Hash) && name_identifier.fetch("nameIdentifierScheme", nil) == "ROR" && name_identifier.fetch("nameIdentifier", nil).present?
sum << ror_from_url(name_identifier.fetch("nameIdentifier", nil))
end
end
sum
sum.uniq
end
end

def fair_organization_id
(Array.wrap(creators) + sponsor_contributors).reduce([]) do |sum, c|
Array.wrap(c.fetch("nameIdentifiers", nil)).each do |name_identifier|
sum << ror_from_url(name_identifier.fetch("nameIdentifier", nil)) if name_identifier.is_a?(Hash) && name_identifier.fetch("nameIdentifierScheme", nil) == "ROR" && name_identifier.fetch("nameIdentifier", nil).present?
if name_identifier.is_a?(Hash) && name_identifier.fetch("nameIdentifierScheme", nil) == "ROR" && name_identifier.fetch("nameIdentifier", nil).present?
sum << ror_from_url(name_identifier.fetch("nameIdentifier", nil))
end
end
sum
sum.uniq
end
end

Expand All @@ -1725,7 +1755,7 @@ def affiliation_id
Array.wrap(c.fetch("affiliation", nil)).each do |affiliation|
sum << ror_from_url(affiliation.fetch("affiliationIdentifier", nil)) if affiliation.is_a?(Hash) && affiliation.fetch("affiliationIdentifierScheme", nil) == "ROR" && affiliation.fetch("affiliationIdentifier", nil).present?
end
sum
sum.uniq
end
end

Expand All @@ -1734,7 +1764,7 @@ def fair_affiliation_id
Array.wrap(c.fetch("affiliation", nil)).each do |affiliation|
sum << ror_from_url(affiliation.fetch("affiliationIdentifier", nil)) if affiliation.is_a?(Hash) && affiliation.fetch("affiliationIdentifierScheme", nil) == "ROR" && affiliation.fetch("affiliationIdentifier", nil).present?
end
sum
sum.uniq
end
end

Expand All @@ -1743,7 +1773,7 @@ def affiliation_id_and_name
Array.wrap(c.fetch("affiliation", nil)).each do |affiliation|
sum << "#{ror_from_url(affiliation.fetch('affiliationIdentifier', nil))}:#{affiliation.fetch('name', nil)}" if affiliation.is_a?(Hash) && affiliation.fetch("affiliationIdentifierScheme", nil) == "ROR" && affiliation.fetch("affiliationIdentifier", nil).present?
end
sum
sum.uniq
end
end

Expand All @@ -1752,7 +1782,7 @@ def fair_affiliation_id_and_name
Array.wrap(c.fetch("affiliation", nil)).each do |affiliation|
sum << "#{ror_from_url(affiliation.fetch('affiliationIdentifier', nil))}:#{affiliation.fetch('name', nil)}" if affiliation.is_a?(Hash) && affiliation.fetch("affiliationIdentifierScheme", nil) == "ROR" && affiliation.fetch("affiliationIdentifier", nil).present?
end
sum
sum.uniq
end
end

Expand Down
45 changes: 45 additions & 0 deletions app/models/doi/indexer/related_doi_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module Doi::Indexer
class RelatedDoiIndexer
def initialize(related_identifiers)
@related_identifiers = related_identifiers
@related_dois = nil
end

def related_dois
@related_dois ||= @related_identifiers.select { |r| r["relatedIdentifierType"] == "DOI" }
end

def related_grouped_by_id
related_dois.group_by { |r| r["relatedIdentifier"].downcase }
end

def relation_types_gouped_by_id
related_grouped_by_id.transform_values do |values|
values.map { |val| val["relationType"].underscore }.uniq
end
end

def related_doi_ids
related_grouped_by_id.keys
end

def dois
Doi.where(doi: related_doi_ids)
end

def indexed_dois
dois.map { |d| RelatedIdentifierDenormalizer.new(d).to_hash }
end

def as_indexed_json
rtypes = relation_types_gouped_by_id
indexed_dois.map do |indexed_doi|
doi = indexed_doi["doi"]
indexed_doi["relation_type"] = rtypes[doi]
indexed_doi
end
end
end
end
32 changes: 32 additions & 0 deletions app/models/doi/indexer/related_identifier_denormalizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module Doi::Indexer
class RelatedIdentifierDenormalizer
attr_reader :related_doi

def initialize(doi)
@related_doi = doi
end

def to_hash
%w[
client_id
doi
organization_id
person_id
resource_type_id
resource_type_id_and_name
].index_with { |method_name| send(method_name) }
end

delegate :resource_type_id, to: :related_doi
delegate :resource_type_id_and_name, to: :related_doi
delegate :organization_id, to: :related_doi
delegate :person_id, to: :related_doi
delegate :client_id, to: :related_doi

def doi
@related_doi.doi.downcase
end
end
end
60 changes: 60 additions & 0 deletions spec/models/doi_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,66 @@
end
end

describe "person_ids" do
it "from creators and contributors" do
subject = build(
:doi,
creators: [
{
"familyName" => "Garza",
"givenName" => "Kristian",
"name" => "Garza, Kristian",
"nameIdentifiers" => [
{
"nameIdentifier" => "https://orcid.org/0000-0003-3484-6875",
"nameIdentifierScheme" => "ORCID",
"schemeUri" => "https://orcid.org",
},
],
"nameType" => "Personal",
"affiliation" => [
{
"name" => "University of Cambridge",
"affiliationIdentifier" => "https://ror.org/013meh722",
"affiliationIdentifierScheme" => "ROR",
},
],
},
],
contributors: [
{
"contributorType" => "Sponsor",
"familyName" => "Bob",
"givenName" => "Jones",
"name" => "Jones, Bob",
"nameIdentifiers" => [
{
"nameIdentifier" => "https://orcid.org/0000-0003-3484-0000",
"nameIdentifierScheme" => "ORCID",
"schemeUri" => "https://orcid.org",
},
],
"nameType" => "Personal",
"affiliation" => [
{
"name" => "University of Examples",
"affiliationIdentifier" => "https://ror.org/013meh8888",
"affiliationIdentifierScheme" => "ROR",
},
],
},
]
)
expect(subject).to be_valid
expect(subject.person_id).to eq(
[
"https://orcid.org/0000-0003-3484-6875",
"https://orcid.org/0000-0003-3484-0000",
]
)
end
end

describe "related_identifiers" do
it "has part" do
subject = build(:doi, related_identifiers: [
Expand Down
60 changes: 60 additions & 0 deletions spec/models/doi_verified_related_identifiers_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

# frozen_string_literal: true

require "rails_helper"

describe Doi, type: :model, vcr: true, elasticsearch: true do
describe "related_doi" do
let(:client) { create(:client) }
let(:target_doi) do
create(:doi,
client: client,
aasm_state: "findable",
types: { "resourceTypeGeneral" => "Dataset" }
)
end
let(:doi) do
create(:doi,
client: client,
aasm_state: "findable",
related_identifiers: [
{
"relatedIdentifier": target_doi.doi,
"relatedIdentifierType": "DOI",
"relationType": "HasPart",
"resourceTypeGeneral": "OutputManagementPlan",
},
{
"relatedIdentifier": target_doi.doi,
"relatedIdentifierType": "DOI",
"relationType": "Cites",
"resourceTypeGeneral": "Text",
}
])
end

it "indexes related_dois" do
expect(doi.related_dois.first["doi"]).to eq(target_doi.doi.downcase)
end

it "indexes related doi's client_id" do
expect(doi.related_dois.first["client_id"]).to eq(target_doi.client_id)
end

it "indexes related doi's person_id" do
expect(doi.related_dois.first["person_id"]).to eq(target_doi.person_id)
end

it "does not index related doi's claimed resource_type_id" do
expect(doi.related_dois.first["resource_type_id"]).not_to eq("output_management_plan")
end

it "indexes related doi's true resource_type_id" do
expect(doi.related_dois.first["resource_type_id"]).to eq("dataset")
end

it "indexes all relations to the related doi" do
expect(doi.related_dois.first["relation_type"]).to eq(["has_part", "cites"])
end
end
end

0 comments on commit ad5b17c

Please sign in to comment.