diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 9d85c04e3..dfd127750 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -18,6 +18,7 @@ class SearchController < ApplicationController :per_page, :category, :search_fields, + :tag_boolean_mode, { tag_names: [], status: [] diff --git a/app/services/search/query_builders/reaction.rb b/app/services/search/query_builders/reaction.rb index be3a68203..f1c1cd7de 100644 --- a/app/services/search/query_builders/reaction.rb +++ b/app/services/search/query_builders/reaction.rb @@ -64,7 +64,13 @@ module Search TERM_KEYS.map do |term_key, search_key| next unless @params.key? term_key - { terms: { search_key => Array.wrap(@params[term_key]) } } + values = Array.wrap(@params[term_key]) + + if params[:tag_boolean_mode] == "all" + values.map { |val| { term: { search_key => val } } } + else + { terms: { search_key => values } } + end end.compact end diff --git a/spec/services/search/reaction_spec.rb b/spec/services/search/reaction_spec.rb index 334f4a9f8..05a407be8 100644 --- a/spec/services/search/reaction_spec.rb +++ b/spec/services/search/reaction_spec.rb @@ -50,11 +50,14 @@ RSpec.describe Search::Reaction, type: :service do end context "with a filter term" do + let(:tag_one) { create(:tag) } + let(:tag_two) { create(:tag) } + it "filters by tag names" do - article1.tags << create(:tag, name: "ruby") - article2.tags << create(:tag, name: "python") + article1.tags << tag_one + article2.tags << tag_two index_documents([reaction1, reaction2]) - query_params[:tag_names] = "ruby" + query_params[:tag_names] = [tag_one.name] reaction_docs = described_class.search_documents(params: query_params)["reactions"] expect(reaction_docs.count).to eq(1) @@ -62,6 +65,20 @@ RSpec.describe Search::Reaction, type: :service do expect(doc_ids).to include(reaction1.id) end + it "filters by multiple tag names when tag_boolean_mode is set to all" do + article1.tags << tag_one + article2.tags << tag_two + article2.tags << tag_one + index_documents([reaction1, reaction2]) + query_params[:tag_names] = [tag_one.name, tag_two.name] + query_params[:tag_boolean_mode] = "all" + + reaction_docs = described_class.search_documents(params: query_params)["reactions"] + expect(reaction_docs.count).to eq(1) + doc_ids = reaction_docs.map { |t| t.dig("id") } + expect(doc_ids).to include(reaction2.id) + end + it "filters by user_id" do index_documents([reaction1, reaction2]) query_params[:user_id] = reaction1.user_id