Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gdt 163 access type filters #803

Merged
merged 4 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/graphql/types/aggregations_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ class AggregationCountType < Types::BaseObject
end

class AggregationsType < Types::BaseObject
field :access_to_files, [Types::AggregationCountType],
null: true,
description: 'Total seach results by access type (which is a Right with description `Access to files`). ' \
'This is only applicable to geospatial records at this time.'
field :format, [Types::AggregationCountType], null: true, description: 'Total search results by format'
field :content_type, [Types::AggregationCountType], null: true, description: 'Total search results by content type'
field :contributors, [Types::AggregationCountType], null: true,
Expand Down
8 changes: 8 additions & 0 deletions app/graphql/types/query_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ def record_id(id:, index:)
argument :source, String, required: false, default_value: 'All', deprecation_reason: 'Use `sourceFilter`'

# applied filters
argument :access_to_files_filter, [String],
required: false, default_value: nil,
description: 'Filter results by access type. Use the `AccessToFiles` ' \
'aggregation for a list of possible values. Multiple ' \
'values are ORed.'

argument :content_type_filter, [String], required: false, default_value: nil,
description: 'Filter results by content type. Use the `contentType` ' \
'aggregation for a list of possible values. Multiple ' \
Expand Down Expand Up @@ -134,6 +140,7 @@ def construct_query(searchterm, citation, contributors, funding_information, geo
query[:locations] = locations
query[:subjects] = subjects
query[:title] = title
query[:access_to_files_filter] = filters[:access_to_files_filter]
query[:collection_filter] = filters[:collection_filter]
query[:content_format_filter] = filters[:format_filter]
query[:content_type_filter] = filters[:content_type_filter]
Expand All @@ -156,6 +163,7 @@ def source_deprecation_handler(query, new_source, old_source)

def collapse_buckets(es_aggs)
{
access_to_files: es_aggs['access_to_files']['only_file_access']['access_types']['buckets'],
contributors: es_aggs['contributors']['contributor_names']['buckets'],
source: es_aggs['source']['buckets'],
subjects: es_aggs['subjects']['subject_names']['buckets'],
Expand Down
3 changes: 3 additions & 0 deletions app/graphql/types/record_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ class RecordType < Types::BaseObject
'publication'
field :highlight, [Types::HighlightType], null: true, description: 'Search term matches in item metadata'
field :score, String, null: true, description: 'Search relevance'
field :provider, String,
null: true,
description: 'The host institution for a resource. Currently only used for geospatial records'

def in_bibliography
@object['related_items']&.map { |i| i['uri'] if i['relationship'] == 'IsCitedBy' }&.compact
Expand Down
27 changes: 27 additions & 0 deletions app/models/aggregations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class Aggregations
# https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html
def self.all
{
access_to_files:,
contributors:,
content_type:,
content_format:,
Expand All @@ -15,6 +16,32 @@ def self.all
}
end

def self.access_to_files
{
nested: {
path: 'rights'
},
aggs: {
only_file_access: {
filter: {
terms: {
'rights.kind': [
'Access to files'
]
}
},
aggs: {
access_types: {
terms: {
field: 'rights.description.keyword'
}
}
}
}
}
}
end

def self.contributors
{
nested: {
Expand Down
28 changes: 28 additions & 0 deletions app/models/opensearch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ def filters(params)
# source aggregation is "OR" and not "AND" so it does not use the filter_field_by_value method
f.push filter_sources(params[:source_filter]) if params[:source_filter]

# access to files aggregation is "OR" and not "AND" so it does not use the filter_field_by_value method
f.push filter_access_to_files(params[:access_to_files_filter]) if params[:access_to_files_filter]

if params[:subjects_filter].present?
params[:subjects_filter].each do |p|
f.push filter_field_by_value('subjects.value.keyword', p)
Expand All @@ -233,6 +236,31 @@ def filter_field_by_value(field, value)
}
end

# multiple access to files values are ORd
def filter_access_to_files(param)
{ nested: {
path: 'rights',
query: {
bool: {
should: access_to_files_array(param)
}
}
} }
end

def access_to_files_array(param)
rights = []
param.each do |right|
rights << {
term: {
'rights.description.keyword': right
}
}
end
rights
end

# multiple sources values are ORd
def filter_sources(param)
{
bool: {
Expand Down
12 changes: 6 additions & 6 deletions test/controllers/graphql_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest
}' }
assert_equal(200, response.status)
json = JSON.parse(response.body)
assert_equal('32.201416', json['data']['search']['records'].first['score'])
assert_equal('32.326054', json['data']['search']['records'].first['score'])
end
end
end
Expand Down Expand Up @@ -166,7 +166,7 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest
}' }
assert_equal(200, response.status)
json = JSON.parse(response.body)
assert(json['data']['search']['records'].first['contributors'].any? { |c| c.value? 'Kim, Moon S. (Moon Sung)' })
assert(json['data']['search']['records'].first['contributors'].any? { |c| c.value? 'Kim, Moon H. (Moon Ho)' })
end
end
end
Expand Down Expand Up @@ -482,7 +482,7 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest
assert_equal('mit alma',
json['data']['search']['aggregations']['source']
.first['key'])
assert_equal(160_288,
assert_equal(208_361,
json['data']['search']['aggregations']['source']
.first['docCount'])
end
Expand All @@ -509,7 +509,7 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest
assert_equal('mit alma',
json['data']['search']['aggregations']['source']
.first['key'])
assert_equal(1_399_825,
assert_equal(1_636_808,
json['data']['search']['aggregations']['source']
.first['docCount'])
end
Expand All @@ -536,7 +536,7 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest
assert_equal('mit alma',
json['data']['search']['aggregations']['source']
.first['key'])
assert_equal(1_399_825,
assert_equal(1_636_808,
json['data']['search']['aggregations']['source']
.first['docCount'])
end
Expand Down Expand Up @@ -574,7 +574,7 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest
}' }
assert_equal(200, response.status)
json = JSON.parse(response.body)
assert_equal(234, json['data']['search']['hits'])
assert_equal(225, json['data']['search']['hits'])
end
end
end
Expand Down
19 changes: 19 additions & 0 deletions test/models/opensearch_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,25 @@ class OpensearchTest < ActiveSupport::TestCase
assert_equal(expected, Opensearch.new.filter_sources(sources))
end

test 'access_to_files_array creates correct query structure' do
rights = ['MIT authentication', 'Free/open to all']
expected = [{ term: { 'rights.description.keyword': 'MIT authentication' } },
{ term: { 'rights.description.keyword': 'Free/open to all' } }]

assert_equal(expected, Opensearch.new.access_to_files_array(rights))
end

test 'filter_access_to_files creates correct query structure' do
sources = ['MIT authentication', 'Free/open to all']
expected = { nested: { path: 'rights',
query: { bool: { should: [
{ term: { 'rights.description.keyword': 'MIT authentication' } },
{ term: { 'rights.description.keyword': 'Free/open to all' } }
] } } } }

assert_equal(expected, Opensearch.new.filter_access_to_files(sources))
end

test 'filter_field_by_value query structure' do
expected = {
term: { fakefield: 'i am a fake value' }
Expand Down
22 changes: 12 additions & 10 deletions test/vcr_cassettes/graphql_apply_multiple_content_types_filters.yml

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 12 additions & 10 deletions test/vcr_cassettes/graphql_filter_multiple_sources.yml

Large diffs are not rendered by default.

22 changes: 12 additions & 10 deletions test/vcr_cassettes/graphql_filter_single_source.yml

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions test/vcr_cassettes/graphql_geobox.yml

Large diffs are not rendered by default.

Loading
Loading