diff --git a/Gemfile b/Gemfile index 3074534d5..56ce5a9d0 100644 --- a/Gemfile +++ b/Gemfile @@ -58,8 +58,8 @@ gem 'audited', '~> 4.8' gem 'git', '~> 1.5' gem 'graphql', '~> 1.9', '>= 1.9.4' gem 'graphql-errors', '~> 0.3.0' -# gem 'graphql-batch', '~> 0.4.0' -# gem 'graphql-cache', '~> 0.6.0' +gem 'graphql-batch', '~> 0.4.0' +gem 'graphql-cache', '~> 0.6.0' group :development, :test do gem 'rspec-rails', '~> 3.8', '>= 3.8.2' diff --git a/Gemfile.lock b/Gemfile.lock index b0d4c09f8..1c1e246cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - aasm (5.0.3) + aasm (5.0.4) concurrent-ruby (~> 1.0) actioncable (5.2.3) actionpack (= 5.2.3) @@ -58,21 +58,21 @@ GEM audited (4.8.0) activerecord (>= 4.0, < 5.3) aws-eventstream (1.0.3) - aws-partitions (1.160.0) - aws-sdk-core (3.50.0) + aws-partitions (1.162.0) + aws-sdk-core (3.52.1) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.18.0) - aws-sdk-core (~> 3, >= 3.48.2) + aws-sdk-kms (1.20.0) + aws-sdk-core (~> 3, >= 3.52.1) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.36.1) - aws-sdk-core (~> 3, >= 3.48.2) + aws-sdk-s3 (1.38.0) + aws-sdk-core (~> 3, >= 3.52.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.0) - aws-sdk-sqs (1.13.0) - aws-sdk-core (~> 3, >= 3.48.2) + aws-sdk-sqs (1.15.0) + aws-sdk-core (~> 3, >= 3.52.1) aws-sigv4 (~> 1.1) aws-sigv4 (1.1.0) aws-eventstream (~> 1.0, >= 1.0.2) @@ -127,13 +127,14 @@ GEM builder (3.2.3) byebug (11.0.1) cancancan (2.3.0) - capybara (3.19.0) + capybara (3.20.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (~> 1.2) + uglifier xpath (~> 3.2) case_transform (0.2) activesupport @@ -201,6 +202,7 @@ GEM nokogiri (>= 1.4.3) erubi (1.8.0) excon (0.64.0) + execjs (2.7.0) facets (3.1.0) factory_bot (4.11.1) activesupport (>= 3.0.0) @@ -231,6 +233,11 @@ GEM globalid (0.4.2) activesupport (>= 4.2.0) graphql (1.9.4) + graphql-batch (0.4.0) + graphql (>= 1.3, < 2) + promise.rb (~> 0.7.2) + graphql-cache (0.6.0) + graphql (~> 1, > 1.8) graphql-errors (0.3.0) graphql (>= 1.6.0, < 2) haml (5.0.4) @@ -321,7 +328,7 @@ GEM i18n (>= 0.6.4, <= 2) msgpack (1.2.10) multi_json (1.13.1) - multipart-post (2.1.0) + multipart-post (2.1.1) mysql2 (0.4.10) namae (1.0.1) netrc (0.11.0) @@ -342,6 +349,7 @@ GEM addressable css_parser (>= 1.6.0) htmlentities (>= 4.0.0) + promise.rb (0.7.4) public_suffix (2.0.5) pwqgen.rb (0.1.0) docopt (~> 0.5) @@ -404,7 +412,7 @@ GEM rdf (>= 2.2, < 4.0) rdf-xsd (3.0.1) rdf (~> 3.0) - regexp_parser (1.4.0) + regexp_parser (1.5.0) request_store (1.4.1) rack (>= 1.4) rest-client (2.0.2) @@ -443,7 +451,7 @@ GEM rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 1.6) - rubocop-performance (1.2.0) + rubocop-performance (1.3.0) rubocop (>= 0.68.0) ruby-enum (0.7.2) i18n @@ -499,6 +507,8 @@ GEM tilt (>= 1.4, < 3) tzinfo (1.2.5) thread_safe (~> 0.1) + uglifier (4.1.20) + execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.7.6) @@ -557,6 +567,8 @@ DEPENDENCIES gender_detector (~> 0.1.2) git (~> 1.5) graphql (~> 1.9, >= 1.9.4) + graphql-batch (~> 0.4.0) + graphql-cache (~> 0.6.0) graphql-errors (~> 0.3.0) iso8601 (~> 0.9.0) json (~> 1.8, >= 1.8.5) diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index d8580d0a4..967017a9a 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -17,7 +17,7 @@ def index if params[:id].present? response = Activity.find_by_id(params[:id]) elsif params[:ids].present? - response = Activity.find_by_ids(params[:ids], page: page, sort: sort) + response = Activity.find_by_id(params[:ids], page: page, sort: sort) else response = Activity.query(params[:query], uid: params[:doi_id], page: page, sort: sort) end diff --git a/app/controllers/clients_controller.rb b/app/controllers/clients_controller.rb index ab18f3cab..5711b746d 100644 --- a/app/controllers/clients_controller.rb +++ b/app/controllers/clients_controller.rb @@ -23,7 +23,7 @@ def index if params[:id].present? response = Client.find_by_id(params[:id]) elsif params[:ids].present? - response = Client.find_by_ids(params[:ids], page: page, sort: sort) + response = Client.find_by_id(params[:ids], page: page, sort: sort) else response = Client.query(params[:query], year: params[:year], provider_id: params[:provider_id], software: params[:software], page: page, sort: sort) end diff --git a/app/controllers/concerns/facetable.rb b/app/controllers/concerns/facetable.rb index 6c1e6831c..421443816 100644 --- a/app/controllers/concerns/facetable.rb +++ b/app/controllers/concerns/facetable.rb @@ -88,7 +88,7 @@ def facet_by_provider(arr) # generate hash with id and name for each provider in facet ids = arr.map { |hsh| hsh["key"] }.join(",") - providers = Provider.find_by_ids(ids, size: 1000).records.pluck(:symbol, :name).to_h + providers = Provider.find_by_id(ids, size: 1000).records.pluck(:symbol, :name).to_h arr.map do |hsh| { "id" => hsh["key"], @@ -163,7 +163,7 @@ def facet_by_provider_ids(arr) def facet_by_client(arr) # generate hash with id and name for each client in facet ids = arr.map { |hsh| hsh["key"] }.join(",") - clients = Client.find_by_ids(ids).records.pluck(:symbol, :name).to_h + clients = Client.find_by_id(ids).records.pluck(:symbol, :name).to_h arr.map do |hsh| { "id" => hsh["key"], diff --git a/app/controllers/data_centers_controller.rb b/app/controllers/data_centers_controller.rb index 83908e902..87323581e 100644 --- a/app/controllers/data_centers_controller.rb +++ b/app/controllers/data_centers_controller.rb @@ -17,7 +17,7 @@ def index if params[:id].present? response = Client.find_by_id(params[:id]) elsif params[:ids].present? - response = Client.find_by_ids(params[:ids], page: page, sort: sort) + response = Client.find_by_id(params[:ids], page: page, sort: sort) else response = Client.query(params[:query], year: params[:year], provider_id: params[:member_id], fields: params[:fields], page: page, sort: sort) end diff --git a/app/controllers/dois_controller.rb b/app/controllers/dois_controller.rb index 430de6da1..0acd667c4 100644 --- a/app/controllers/dois_controller.rb +++ b/app/controllers/dois_controller.rb @@ -46,7 +46,7 @@ def index response = Doi.find_by_id(params[:id]) }.to_s + " ms" elsif params[:ids].present? - response = Doi.find_by_ids(params[:ids], page: page, sort: sort) + response = Doi.find_by_id(params[:ids], page: page, sort: sort) else response = Doi.query(params[:query], state: params[:state], diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index bd96144e6..647d01678 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -16,7 +16,7 @@ def index if params[:id].present? response = Provider.find_by_id(params[:id]) elsif params[:ids].present? - response = Provider.find_by_ids(params[:ids], page: page, sort: sort) + response = Provider.find_by_id(params[:ids], page: page, sort: sort) else response = Provider.query(params[:query], all_members: true, year: params[:year], region: params[:region], organization_type: params[:organization_type], focus_area: params[:focus_area], fields: params[:fields], page: page, sort: sort) end diff --git a/app/controllers/providers_controller.rb b/app/controllers/providers_controller.rb index cec2f6ffc..3d63f3c2e 100644 --- a/app/controllers/providers_controller.rb +++ b/app/controllers/providers_controller.rb @@ -23,7 +23,7 @@ def index if params[:id].present? response = Provider.find_by_id(params[:id]) elsif params[:ids].present? - response = Provider.find_by_ids(params[:ids], page: page, sort: sort) + response = Provider.find_by_id(params[:ids], page: page, sort: sort) else response = Provider.query(params[:query], year: params[:year], region: params[:region], organization_type: params[:organization_type], focus_area: params[:focus_area], page: page, sort: sort) end diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 581a990a5..617dad9a8 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -30,7 +30,7 @@ def index if params[:id].present? response = Doi.find_by_id(params[:id]) elsif params[:ids].present? - response = Doi.find_by_ids(params[:ids], page: page, sort: sort) + response = Doi.find_by_id(params[:ids], page: page, sort: sort) else response = Doi.query(params[:query], state: "findable", diff --git a/app/graphql/active_record_loader.rb b/app/graphql/active_record_loader.rb new file mode 100644 index 000000000..a4b40e846 --- /dev/null +++ b/app/graphql/active_record_loader.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class ActiveRecordLoader < GraphQL::Batch::Loader + def initialize(model) + @model = model + end + + def perform(ids) + @model.where(id: ids).each { |record| fulfill(record.id, record) } + ids.each { |id| fulfill(id, nil) unless fulfilled?(id) } + end +end diff --git a/app/graphql/elasticsearch_loader.rb b/app/graphql/elasticsearch_loader.rb new file mode 100644 index 000000000..6a8714c90 --- /dev/null +++ b/app/graphql/elasticsearch_loader.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class ElasticsearchLoader < GraphQL::Batch::Loader + def initialize(model) + @model = model + end + + def perform(ids) + @model.find_by_id(ids).results.each { |record| fulfill(record.uid, record) } + ids.each { |id| fulfill(id, nil) unless fulfilled?(id) } + end +end diff --git a/app/graphql/lupo_schema.rb b/app/graphql/lupo_schema.rb index 137d867db..e715fc39f 100644 --- a/app/graphql/lupo_schema.rb +++ b/app/graphql/lupo_schema.rb @@ -6,6 +6,9 @@ class LupoSchema < GraphQL::Schema # mutation(Types::MutationType) query(QueryType) + + use GraphQL::Batch + use GraphQL::Cache end GraphQL::Errors.configure(LupoSchema) do diff --git a/app/graphql/types/base_connection.rb b/app/graphql/types/base_connection.rb new file mode 100644 index 000000000..63d5c0a46 --- /dev/null +++ b/app/graphql/types/base_connection.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +class BaseConnection < GraphQL::Types::Relay::BaseConnection +end diff --git a/app/graphql/types/base_interface.rb b/app/graphql/types/base_interface.rb index 45a134654..6d50f2c9d 100644 --- a/app/graphql/types/base_interface.rb +++ b/app/graphql/types/base_interface.rb @@ -2,4 +2,6 @@ module BaseInterface include GraphQL::Schema::Interface + + field_class GraphQL::Cache::Field end diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index 75e283cce..068d1556f 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true class BaseObject < GraphQL::Schema::Object + field_class GraphQL::Cache::Field end diff --git a/app/graphql/types/client_connection_with_meta_type.rb b/app/graphql/types/client_connection_with_meta_type.rb index ad2864972..8b0414f20 100644 --- a/app/graphql/types/client_connection_with_meta_type.rb +++ b/app/graphql/types/client_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClientConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ClientConnectionWithMetaType < BaseConnection edge_type(ClientEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/client_dataset_connection_with_meta_type.rb b/app/graphql/types/client_dataset_connection_with_meta_type.rb index 0e788f9c4..a5e3457ae 100644 --- a/app/graphql/types/client_dataset_connection_with_meta_type.rb +++ b/app/graphql/types/client_dataset_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClientDatasetConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ClientDatasetConnectionWithMetaType < BaseConnection edge_type(DatasetEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/client_publication_connection_with_meta_type.rb b/app/graphql/types/client_publication_connection_with_meta_type.rb index c229fa3aa..05a4aa65e 100644 --- a/app/graphql/types/client_publication_connection_with_meta_type.rb +++ b/app/graphql/types/client_publication_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClientPublicationConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ClientPublicationConnectionWithMetaType < BaseConnection edge_type(DatasetEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/client_software_connection_with_meta_type.rb b/app/graphql/types/client_software_connection_with_meta_type.rb index ffdde48e6..a19cdee05 100644 --- a/app/graphql/types/client_software_connection_with_meta_type.rb +++ b/app/graphql/types/client_software_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClientSoftwareConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ClientSoftwareConnectionWithMetaType < BaseConnection edge_type(DatasetEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/dataset_connection_with_meta_type.rb b/app/graphql/types/dataset_connection_with_meta_type.rb index bd2cf02bf..91673ab1c 100644 --- a/app/graphql/types/dataset_connection_with_meta_type.rb +++ b/app/graphql/types/dataset_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DatasetConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class DatasetConnectionWithMetaType < BaseConnection edge_type(DatasetEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/funder_connection_with_meta_type.rb b/app/graphql/types/funder_connection_with_meta_type.rb index 8e1692f08..506de7d34 100644 --- a/app/graphql/types/funder_connection_with_meta_type.rb +++ b/app/graphql/types/funder_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class FunderConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class FunderConnectionWithMetaType < BaseConnection edge_type(FunderEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/funder_dataset_connection_with_meta_type.rb b/app/graphql/types/funder_dataset_connection_with_meta_type.rb index 0473a2e13..2b1aee408 100644 --- a/app/graphql/types/funder_dataset_connection_with_meta_type.rb +++ b/app/graphql/types/funder_dataset_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class FunderDatasetConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class FunderDatasetConnectionWithMetaType < BaseConnection edge_type(EventDataEdgeType, edge_class: EventDataEdge) field :total_count, Integer, null: false diff --git a/app/graphql/types/funder_publication_connection_with_meta_type.rb b/app/graphql/types/funder_publication_connection_with_meta_type.rb index 6b9fc501c..79989c5a7 100644 --- a/app/graphql/types/funder_publication_connection_with_meta_type.rb +++ b/app/graphql/types/funder_publication_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class FunderPublicationConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class FunderPublicationConnectionWithMetaType < BaseConnection edge_type(EventDataEdgeType, edge_class: EventDataEdge) field :total_count, Integer, null: false diff --git a/app/graphql/types/funder_software_connection_with_meta_type.rb b/app/graphql/types/funder_software_connection_with_meta_type.rb index 1723f7b60..9e5f419b9 100644 --- a/app/graphql/types/funder_software_connection_with_meta_type.rb +++ b/app/graphql/types/funder_software_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class FunderSoftwareConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class FunderSoftwareConnectionWithMetaType < BaseConnection edge_type(EventDataEdgeType, edge_class: EventDataEdge) field :total_count, Integer, null: false diff --git a/app/graphql/types/funder_type.rb b/app/graphql/types/funder_type.rb index 5cd3323c5..530be5b60 100644 --- a/app/graphql/types/funder_type.rb +++ b/app/graphql/types/funder_type.rb @@ -24,22 +24,22 @@ class FunderType < BaseObject def datasets(**args) ids = Event.query(nil, obj_id: object[:id], citation_type: "Dataset-Funder").fetch(:data, []).map do |e| doi_from_url(e[:subj_id]) - end.join(",") - Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a + end + ElasticsearchLoader.for(Doi).load_many(ids) end def publications(**args) ids = Event.query(nil, obj_id: object[:id], citation_type: "Funder-ScholarlyArticle").fetch(:data, []).map do |e| doi_from_url(e[:subj_id]) - end.join(",") - Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a + end + ElasticsearchLoader.for(Doi).load_many(ids) end def softwares(**args) ids = Event.query(nil, obj_id: object[:id], citation_type: "Funder-SoftwareSourceCode").fetch(:data, []).map do |e| doi_from_url(e[:subj_id]) - end.join(",") - Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a + end + ElasticsearchLoader.for(Doi).load_many(ids) end def doi_from_url(url) diff --git a/app/graphql/types/organization_connection_with_meta_type.rb b/app/graphql/types/organization_connection_with_meta_type.rb index b56287a08..acc127311 100644 --- a/app/graphql/types/organization_connection_with_meta_type.rb +++ b/app/graphql/types/organization_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class OrganizationConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class OrganizationConnectionWithMetaType < BaseConnection edge_type(OrganizationEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/prefix_connection_with_meta_type.rb b/app/graphql/types/prefix_connection_with_meta_type.rb index e4e7224ac..5dc9cd697 100644 --- a/app/graphql/types/prefix_connection_with_meta_type.rb +++ b/app/graphql/types/prefix_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PrefixConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class PrefixConnectionWithMetaType < BaseConnection edge_type(PrefixEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/provider_connection_with_meta_type.rb b/app/graphql/types/provider_connection_with_meta_type.rb index c2dd9e36f..96a1402e4 100644 --- a/app/graphql/types/provider_connection_with_meta_type.rb +++ b/app/graphql/types/provider_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ProviderConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ProviderConnectionWithMetaType < BaseConnection edge_type(ProviderEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/publication_connection_with_meta_type.rb b/app/graphql/types/publication_connection_with_meta_type.rb index aa7489d57..70dda83e2 100644 --- a/app/graphql/types/publication_connection_with_meta_type.rb +++ b/app/graphql/types/publication_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PublicationConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class PublicationConnectionWithMetaType < BaseConnection edge_type(DatasetEdgeType) field :total_count, Integer, null: false diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 659a0d8cb..87d2202ec 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -14,7 +14,7 @@ def providers(query: nil) end def provider(id:) - Provider.unscoped.where("allocator.role_name IN ('ROLE_ALLOCATOR', 'ROLE_ADMIN')").where(deleted_at: nil).where(symbol: id).first + ElasticsearchLoader.for(Provider).load(id) end field :clients, ClientConnectionWithMetaType, null: false, connection: true, max_page_size: 100 do @@ -32,7 +32,7 @@ def clients(query: nil, year: nil, software: nil) end def client(id:) - Client.where(symbol: id).where(deleted_at: nil).first + ElasticsearchLoader.for(Client).load(id) end field :prefixes, [PrefixType], null: false do @@ -368,7 +368,7 @@ def set_doi(id) doi = doi_from_url(id) fail ActiveRecord::RecordNotFound if doi.nil? - result = Doi.find_by_id(doi).first + result = ElasticsearchLoader.for(Doi).load(doi) fail ActiveRecord::RecordNotFound if result.nil? result diff --git a/app/graphql/types/researcher_dataset_connection_with_meta_type.rb b/app/graphql/types/researcher_dataset_connection_with_meta_type.rb index 030731b78..245954fba 100644 --- a/app/graphql/types/researcher_dataset_connection_with_meta_type.rb +++ b/app/graphql/types/researcher_dataset_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ResearcherDatasetConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ResearcherDatasetConnectionWithMetaType < BaseConnection edge_type(EventDataEdgeType, edge_class: EventDataEdge) field :total_count, Integer, null: false diff --git a/app/graphql/types/researcher_publication_connection_with_meta_type.rb b/app/graphql/types/researcher_publication_connection_with_meta_type.rb index 4d694f0e5..3ab4cdf1d 100644 --- a/app/graphql/types/researcher_publication_connection_with_meta_type.rb +++ b/app/graphql/types/researcher_publication_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ResearcherPublicationConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ResearcherPublicationConnectionWithMetaType < BaseConnection edge_type(EventDataEdgeType, edge_class: EventDataEdge) field :total_count, Integer, null: false diff --git a/app/graphql/types/researcher_software_connection_with_meta_type.rb b/app/graphql/types/researcher_software_connection_with_meta_type.rb index 78555f94e..6294ad7ee 100644 --- a/app/graphql/types/researcher_software_connection_with_meta_type.rb +++ b/app/graphql/types/researcher_software_connection_with_meta_type.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ResearcherSoftwareConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class ResearcherSoftwareConnectionWithMetaType < BaseConnection edge_type(EventDataEdgeType, edge_class: EventDataEdge) field :total_count, Integer, null: false diff --git a/app/graphql/types/researcher_type.rb b/app/graphql/types/researcher_type.rb index 9709794a4..d26272f57 100644 --- a/app/graphql/types/researcher_type.rb +++ b/app/graphql/types/researcher_type.rb @@ -24,22 +24,22 @@ class ResearcherType < BaseObject def datasets(**args) ids = Event.query(nil, obj_id: https_to_http(object[:id]), citation_type: "Dataset-Person").fetch(:data, []).map do |e| doi_from_url(e[:subj_id]) - end.join(",") - Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a + end + ElasticsearchLoader.for(Doi).load_many(ids) end def publications(**args) ids = Event.query(nil, obj_id: https_to_http(object[:id]), citation_type: "Person-ScholarlyArticle").fetch(:data, []).map do |e| doi_from_url(e[:subj_id]) - end.join(",") - Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a + end + ElasticsearchLoader.for(Doi).load_many(ids) end def softwares(**args) ids = Event.query(nil, obj_id: https_to_http(object[:id]), citation_type: "Person-SoftwareSourceCode").fetch(:data, []).map do |e| doi_from_url(e[:subj_id]) - end.join(",") - Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a + end + ElasticsearchLoader.for(Doi).load_many(ids) end def doi_from_url(url) diff --git a/app/graphql/types/software_connection_with_meta_type.rb b/app/graphql/types/software_connection_with_meta_type.rb index 63e3dec04..d21d65460 100644 --- a/app/graphql/types/software_connection_with_meta_type.rb +++ b/app/graphql/types/software_connection_with_meta_type.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -class SoftwareConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection +class SoftwareConnectionWithMetaType < BaseConnection edge_type(DatasetEdgeType) field :total_count, Integer, null: false def total_count args = object.arguments + Doi.query(args[:query], resource_type_id: "Software", state: "findable", page: { number: 1, size: args[:first] }).results.total end end diff --git a/app/models/concerns/indexable.rb b/app/models/concerns/indexable.rb index 89bd4fdc4..00e308ad0 100644 --- a/app/models/concerns/indexable.rb +++ b/app/models/concerns/indexable.rb @@ -53,37 +53,28 @@ def send_message(body, options={}) end module ClassMethods - # don't raise an exception when not found - def find_by_id(id, options={}) - return nil unless id.present? + # return results for one or more ids + def find_by_id(ids, options={}) + ids = ids.split(",") if ids.is_a?(String) + options[:page] ||= {} + options[:page][:number] ||= 1 + options[:page][:size] ||= 25 + options[:sort] ||= { created: { order: "asc" }} __elasticsearch__.search({ - query: { - term: { - symbol: id.upcase - } - }, - aggregations: query_aggregations - }) - end - - def find_by_id_list(ids, options={}) - options[:sort] ||= { "_doc" => { order: 'asc' }} - - __elasticsearch__.search({ - from: options[:page].present? ? (options.dig(:page, :number) - 1) * options.dig(:page, :size) : 0, + from: (options.dig(:page, :number) - 1) * options.dig(:page, :size), size: options[:size] || 25, sort: [options[:sort]], query: { terms: { - id: ids.split(",") + symbol: ids.map(&:upcase) } }, aggregations: query_aggregations }) end - def find_by_ids(ids, options={}) + def find_by_id_list(ids, options={}) options[:sort] ||= { "_doc" => { order: 'asc' }} __elasticsearch__.search({ @@ -92,7 +83,7 @@ def find_by_ids(ids, options={}) sort: [options[:sort]], query: { terms: { - symbol: ids.split(",").map(&:upcase) + id: ids.split(",") } }, aggregations: query_aggregations @@ -101,7 +92,9 @@ def find_by_ids(ids, options={}) def query(query, options={}) aggregations = options[:totals_agg] == true ? totals_aggregations : query_aggregations - options[:page] ||= { size: 25, number: 1 } + options[:page] ||= {} + options[:page][:number] ||= 1 + options[:page][:size] ||= 25 # enable cursor-based pagination for DOIs if self.name == "Doi" && options.dig(:page, :cursor).present? diff --git a/app/models/doi.rb b/app/models/doi.rb index 30ab8ce75..a652812ad 100644 --- a/app/models/doi.rb +++ b/app/models/doi.rb @@ -354,13 +354,22 @@ def self.sub_aggregations # ['doi^10', 'titles.title^10', 'creator_names^10', 'creators.name^10', 'creators.id^10', 'publisher^10', 'descriptions.description^10', 'types.resourceTypeGeneral^10', 'subjects.subject^10', 'identifiers.identifier^10', 'related_identifiers.relatedIdentifier^10', '_all'] # end - def self.find_by_id(id, options={}) - return nil unless id.present? + # return results for one or more ids + def self.find_by_id(ids, options={}) + ids = ids.split(",") if ids.is_a?(String) + + options[:page] ||= {} + options[:page][:number] ||= 1 + options[:page][:size] ||= 25 + options[:sort] ||= { created: { order: "asc" }} __elasticsearch__.search({ + from: (options.dig(:page, :number) - 1) * options.dig(:page, :size), + size: options[:size] || 25, + sort: [options[:sort]], query: { - term: { - doi: id.upcase + terms: { + doi: ids.map(&:upcase) } }, aggregations: query_aggregations @@ -710,22 +719,6 @@ def media_ids media.pluck(:id).map { |m| Base32::URL.encode(m, split: 4, length: 16) }.compact end - def self.find_by_ids(ids, options={}) - dois = ids.split(",").map(&:upcase) - - __elasticsearch__.search({ - from: 0, - size: 1000, - sort: [{ created: { order: 'asc' }}], - query: { - terms: { - doi: dois - } - }, - aggregations: query_aggregations - }) - end - def xml_encoded Base64.strict_encode64(xml) if xml.present? rescue ArgumentError => exception diff --git a/spec/concerns/indexable_spec.rb b/spec/concerns/indexable_spec.rb index 97a2ccb8d..654090ec7 100644 --- a/spec/concerns/indexable_spec.rb +++ b/spec/concerns/indexable_spec.rb @@ -33,8 +33,8 @@ expect(result.symbol).to eq(client.symbol) end - it 'find_by_ids' do - results = Client.find_by_ids(client.symbol).results + it 'find_by_id multiple' do + results = Client.find_by_id(client.symbol).results expect(results.total).to eq(1) end @@ -57,8 +57,8 @@ expect(result.symbol).to eq(provider.symbol) end - it 'find_by_ids' do - results = Provider.find_by_ids(provider.symbol).results + it 'find_by_id multiple' do + results = Provider.find_by_id(provider.symbol).results expect(results.total).to eq(1) end