Skip to content
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
62 changes: 31 additions & 31 deletions app/graphql/types/query_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,23 @@ def record_id(id:, index:)
argument :index, String, required: false, default_value: nil,
description: 'It is not recommended to provide an index value unless we have provided you with one for your specific use case'

argument :source, String, required: false, default_value: 'All', deprecation_reason: 'Use `sourceFacet`'

# applied facets
argument :content_type_facet, [String], required: false, default_value: nil,
description: 'Filter results by content type. Use the `contentType` aggregation for a list of possible values'
argument :contributors_facet, [String], required: false, default_value: nil,
description: 'Filter results by contributor. Use the `contributors` aggregation for a list of possible values'
argument :format_facet, [String], required: false, default_value: nil,
description: 'Filter results by format. Use the `format` aggregation for a list of possible values'
argument :languages_facet, [String], required: false, default_value: nil,
description: 'Filter results by language. Use the `languages` aggregation for a list of possible values'
argument :literary_form_facet, String, required: false, default_value: nil,
description: 'Filter results by fiction or nonfiction'
argument :source_facet, [String], required: false, default_value: nil,
description: 'Filter by source record system. Use the `sources` aggregation for a list of possible values'
argument :subjects_facet, [String], required: false, default_value: nil,
description: 'Filter by subject terms. Use the `contentType` aggregation for a list of possible values'
argument :source, String, required: false, default_value: 'All', deprecation_reason: 'Use `sourceFilter`'

# applied filters
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'
argument :contributors_filter, [String], required: false, default_value: nil,
description: 'Filter results by contributor. Use the `contributors` aggregation for a list of possible values'
argument :format_filter, [String], required: false, default_value: nil,
description: 'Filter results by format. Use the `format` aggregation for a list of possible values'
argument :languages_filter, [String], required: false, default_value: nil,
description: 'Filter results by language. Use the `languages` aggregation for a list of possible values'
argument :literary_form_filter, String, required: false, default_value: nil,
description: 'Filter results by fiction or nonfiction'
argument :source_filter, [String], required: false, default_value: nil,
description: 'Filter by source record system. Use the `sources` aggregation for a list of possible values'
argument :subjects_filter, [String], required: false, default_value: nil,
description: 'Filter by subject terms. Use the `contentType` aggregation for a list of possible values'
end
else
def record_id(id:)
Expand Down Expand Up @@ -104,9 +104,9 @@ def record_id(id:)

if Flipflop.v2?
def search(searchterm:, citation:, contributors:, funding_information:, identifiers:, locations:, subjects:,
title:, index:, source:, from:, **facets)
title:, index:, source:, from:, **filters)
query = construct_query(searchterm, citation, contributors, funding_information, identifiers, locations,
subjects, title, source, facets)
subjects, title, source, filters)

results = Opensearch.new.search(from, query, Timdex::OSClient, highlight_requested?, index)

Expand Down Expand Up @@ -150,7 +150,7 @@ def search(searchterm:, from:, **facets)

if Flipflop.v2?
def construct_query(searchterm, citation, contributors, funding_information, identifiers, locations, subjects,
title, source, facets)
title, source, filters)
query = {}
query[:q] = searchterm
query[:citation] = citation
Expand All @@ -160,22 +160,22 @@ def construct_query(searchterm, citation, contributors, funding_information, ide
query[:locations] = locations
query[:subjects] = subjects
query[:title] = title
query[:collection_facet] = facets[:collection_facet]
query[:content_format_facet] = facets[:format_facet]
query[:content_type_facet] = facets[:content_type_facet]
query[:contributors_facet] = facets[:contributors_facet]
query[:languages_facet] = facets[:languages_facet]
query[:literary_form_facet] = facets[:literary_form_facet]
query = source_deprecation_handler(query, facets[:source_facet], source)
query[:subjects_facet] = facets[:subjects_facet]
query[:collection_filter] = filters[:collection_filter]
query[:content_format_filter] = filters[:format_filter]
query[:content_type_filter] = filters[:content_type_filter]
query[:contributors_filter] = filters[:contributors_filter]
query[:languages_filter] = filters[:languages_filter]
query[:literary_form_filter] = filters[:literary_form_filter]
query = source_deprecation_handler(query, filters[:source_filter], source)
query[:subjects_filter] = filters[:subjects_filter]
query
end

# source_deprecation_handler prefers our new `sourceFacet` array but will fall back on the
# source_deprecation_handler prefers our new `sourceFilter` array but will fall back on the
# depreacted `source` String if it is present and the new version is not
def source_deprecation_handler(query, new_source, old_source)
query[:source_facet] = [old_source] if old_source != 'All' && old_source.present?
query[:source_facet] = new_source if new_source != 'All' && new_source.present?
query[:source_filter] = [old_source] if old_source != 'All' && old_source.present?
query[:source_filter] = new_source if new_source != 'All' && new_source.present?
query
end
else
Expand Down
27 changes: 15 additions & 12 deletions app/models/opensearch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,38 +113,41 @@ def matches
def filters(params)
f = []

if params[:contributors_facet].present?
params[:contributors_facet].each do |p|
if params[:contributors_filter].present?
params[:contributors_filter].each do |p|
f.push filter_field_by_value('contributors.value.keyword', p)
end
end

if params[:content_type_facet].present?
params[:content_type_facet].each do |p|
if params[:content_type_filter].present?
params[:content_type_filter].each do |p|
f.push filter_field_by_value('content_type', p)
end
end

if params[:content_format_facet].present?
params[:content_format_facet].each do |p|
if params[:content_format_filter].present?
params[:content_format_filter].each do |p|
f.push filter_field_by_value('format', p)
end
end

if params[:languages_facet].present?
params[:languages_facet].each do |p|
if params[:languages_filter].present?
params[:languages_filter].each do |p|
f.push filter_field_by_value('languages', p)
end
end

# literary_form is a single value aggregation
f.push filter_field_by_value('literary_form', params[:literary_form_facet]) if params[:literary_form_facet].present?
if params[:literary_form_filter].present?
f.push filter_field_by_value('literary_form',
params[:literary_form_filter])
end

# source aggregation is "OR" and not "AND" so it does not use the filter_field_by_value method
f.push filter_sources(params[:source_facet]) if params[:source_facet]
f.push filter_sources(params[:source_filter]) if params[:source_filter]

if params[:subjects_facet].present?
params[:subjects_facet].each do |p|
if params[:subjects_filter].present?
params[:subjects_filter].each do |p|
f.push filter_field_by_value('subjects.value.keyword', p)
end
end
Expand Down
28 changes: 14 additions & 14 deletions test/controllers/graphql_controller_v2_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ def setup
end
end

test 'graphqlv2 search with source facet applied' do
test 'graphqlv2 search with source filter applied' do
VCR.use_cassette('graphql v2 search a only alma') do
post '/graphql', params: { query: '{
search(searchterm: "a",
sourceFacet: "MIT Alma") {
sourceFilter: "MIT Alma") {
hits
aggregations {
source {
Expand Down Expand Up @@ -261,7 +261,7 @@ def setup
VCR.use_cassette('graphql v2 search multiple subjects') do
post '/graphql', params: { query: '{
search(searchterm: "space",
subjectsFacet: ["space and time.",
subjectsFilter: ["space and time.",
"quantum theory."]) {
hits
}
Expand All @@ -272,7 +272,7 @@ def setup
end
end

test 'graphqlv2 search with invalid facet applied' do
test 'graphqlv2 search with invalid filter applied' do
post '/graphql', params: { query: '{
search(searchterm: "wright",
fake: "mit archivesspace") {
Expand All @@ -292,12 +292,12 @@ def setup
json['errors'].first['message'])
end

test 'graphqlv2 valid facets can result in no results' do
test 'graphqlv2 valid filters can result in no results' do
skip 'opensearch model is not updated to allow this yet'
VCR.use_cassette('graphql v2 legal facets can result in no results') do
VCR.use_cassette('graphql v2 legal filters can result in no results') do
post '/graphql', params: { query: '{
search(searchterm: "wright",
subjectsFacet: ["fake facet value"]) {
subjectsFilter: ["fake filter value"]) {
hits
aggregations {
source {
Expand Down Expand Up @@ -362,7 +362,7 @@ def setup
# filtering to 2 sources returns 2 sources
post '/graphql', params: { query:
'{
search(searchterm: "data", sourceFacet: ["Zenodo", "DSpace@MIT"]) {
search(searchterm: "data", sourceFilter: ["Zenodo", "DSpace@MIT"]) {
hits
aggregations {
source {
Expand Down Expand Up @@ -408,7 +408,7 @@ def setup
# filtering to 1 sources returns 1 source
post '/graphql', params: { query:
'{
search(searchterm: "data", sourceFacet: ["DSpace@MIT"]) {
search(searchterm: "data", sourceFilter: ["DSpace@MIT"]) {
hits
aggregations {
source {
Expand Down Expand Up @@ -464,13 +464,13 @@ def setup
end
end

test 'graphqlv2 can apply multi-value facets' do
# fragile test: facet data required to have at least 2 records with both
test 'graphqlv2 can apply multi-value filters' do
# fragile test: filter data required to have at least 2 records with both
# `dataset` and `still image` contentTypes
VCR.use_cassette('graphql v2 apply multiple content types facets') do
VCR.use_cassette('graphql v2 apply multiple content types filters') do
post '/graphql', params: { query:
'{
search(index: "rdi*", contentTypeFacet:["dataset"]) {
search(index: "rdi*", contentTypeFilter:["dataset"]) {
hits
aggregations {
contentType {
Expand All @@ -489,7 +489,7 @@ def setup

post '/graphql', params: { query:
'{
search(index: "rdi*", contentTypeFacet:["dataset", "still image"]) {
search(index: "rdi*", contentTypeFilter:["dataset", "still image"]) {
hits
aggregations {
contentType {
Expand Down
44 changes: 22 additions & 22 deletions test/models/opensearch_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,118 +136,118 @@ class OpensearchTest < ActiveSupport::TestCase
assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for single contributors_facet' do
test 'filters query structure for single contributors_filter' do
expected_filters =
[
{ term: { 'contributors.value.keyword': 'Lastname, Firstname' } }
]
params = { contributors_facet: ['Lastname, Firstname'] }
params = { contributors_filter: ['Lastname, Firstname'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for multiple contributors_facet' do
test 'filters query structure for multiple contributors_filter' do
expected_filters =
[
{ term: { 'contributors.value.keyword': 'Lastname, Firstname' } },
{ term: { 'contributors.value.keyword': 'Another name' } }
]
params = { contributors_facet: ['Lastname, Firstname', 'Another name'] }
params = { contributors_filter: ['Lastname, Firstname', 'Another name'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for single content_type_facet' do
test 'filters query structure for single content_type_filter' do
expected_filters =
[
{ term: { content_type: 'cheese' } }
]
params = { content_type_facet: ['cheese'] }
params = { content_type_filter: ['cheese'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for multiple content_type_facet' do
test 'filters query structure for multiple content_type_filter' do
expected_filters =
[
{ term: { content_type: 'cheese' } },
{ term: { content_type: 'ice cream' } }
]
params = { content_type_facet: ['cheese', 'ice cream'] }
params = { content_type_filter: ['cheese', 'ice cream'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for single content_format_facet' do
test 'filters query structure for single content_format_filter' do
expected_filters =
[
{ term: { format: 'cheese' } }
]
params = { content_format_facet: ['cheese'] }
params = { content_format_filter: ['cheese'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for multiple content_format_facet' do
test 'filters query structure for multiple content_format_filter' do
expected_filters =
[
{ term: { format: 'cheese' } },
{ term: { format: 'ice cream' } }
]
params = { content_format_facet: ['cheese', 'ice cream'] }
params = { content_format_filter: ['cheese', 'ice cream'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for single languages_facet' do
test 'filters query structure for single languages_filter' do
expected_filters =
[
{ term: { languages: 'cheese' } }
]
params = { languages_facet: ['cheese'] }
params = { languages_filter: ['cheese'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for multiple languages_facet' do
test 'filters query structure for multiple languages_filter' do
expected_filters =
[
{ term: { languages: 'cheese' } },
{ term: { languages: 'ice cream' } }
]
params = { languages_facet: ['cheese', 'ice cream'] }
params = { languages_filter: ['cheese', 'ice cream'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

# literary form is only single value
test 'filters query structure for literary_form_facet' do
test 'filters query structure for literary_form_filter' do
expected_filters =
[
{ term: { literary_form: 'cheese' } }
]
params = { literary_form_facet: 'cheese' }
params = { literary_form_filter: 'cheese' }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for single subjects_facet' do
test 'filters query structure for single subjects_filter' do
expected_filters =
[
{ term: { 'subjects.value.keyword': 'cheese' } }
]
params = { subjects_facet: ['cheese'] }
params = { subjects_filter: ['cheese'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end

test 'filters query structure for multiple subjects_facet' do
test 'filters query structure for multiple subjects_filter' do
expected_filters =
[
{ term: { 'subjects.value.keyword': 'cheese' } },
{ term: { 'subjects.value.keyword': 'ice cream' } }
]
params = { subjects_facet: ['cheese', 'ice cream'] }
params = { subjects_filter: ['cheese', 'ice cream'] }

assert_equal(expected_filters, Opensearch.new.filters(params))
end
Expand Down