Commit fb09d690 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch '33678-allow-revert-back-to-basic-search' into 'master'

Allow user to revert back to non-ElasticSearch search

See merge request gitlab-org/gitlab!19136
parents a171c73e fe56c85b
# frozen_string_literal: true # frozen_string_literal: true
module SearchHelper module SearchHelper
SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets].freeze
def search_autocomplete_opts(term) def search_autocomplete_opts(term)
return unless current_user return unless current_user
...@@ -200,7 +202,7 @@ module SearchHelper ...@@ -200,7 +202,7 @@ module SearchHelper
search_params = params search_params = params
.merge(search) .merge(search)
.merge({ scope: scope }) .merge({ scope: scope })
.permit(:search, :scope, :project_id, :group_id, :repository_ref, :snippets) .permit(SEARCH_PERMITTED_PARAMS)
if @scope == scope if @scope == scope
li_class = 'active' li_class = 'active'
......
- if @search_objects.to_a.empty? - if @search_objects.to_a.empty?
= render partial: "search/results/empty" = render partial: "search/results/empty"
= render_if_exists 'shared/promotions/promote_advanced_search' = render_if_exists 'shared/promotions/promote_advanced_search'
= render_if_exists 'search/form_revert_to_basic'
- else - else
.row-content-block.d-md-flex.text-left.align-items-center .row-content-block.d-md-flex.text-left.align-items-center
- unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount) - unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount)
......
...@@ -583,3 +583,12 @@ Here are some common pitfalls and how to overcome them: ...@@ -583,3 +583,12 @@ Here are some common pitfalls and how to overcome them:
AWS has [fixed limits](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html) AWS has [fixed limits](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html)
for this setting ("Maximum Size of HTTP Request Payloads"), based on the size of for this setting ("Maximum Size of HTTP Request Payloads"), based on the size of
the underlying instance. the underlying instance.
### Reverting to basic search
Sometimes there may be issues with your Elasticsearch index data and as such
GitLab will allow you to revert to "basic search" when there are no search
results and assuming that basic search is supported in that scope. This "basic
search" will behave as though you don't have Elasticsearch enabled at all for
your instance and search using other data sources (ie. Postgres data and Git
data).
...@@ -3,6 +3,8 @@ module EE ...@@ -3,6 +3,8 @@ module EE
module SearchHelper module SearchHelper
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
SWITCH_TO_BASIC_SEARCHABLE_TABS = %w[projects issues merge_requests milestones users].freeze
override :search_filter_input_options override :search_filter_input_options
def search_filter_input_options(type) def search_filter_input_options(type)
options = super options = super
...@@ -60,6 +62,23 @@ module EE ...@@ -60,6 +62,23 @@ module EE
end end
end end
def revert_to_basic_search_filter_url
search_params = params
.permit(::SearchHelper::SEARCH_PERMITTED_PARAMS)
.merge(basic_search: true)
search_path(search_params)
end
def show_switch_to_basic_search?(search_service)
return false unless ::Feature.enabled?(:switch_to_basic_search, default_enabled: false)
return false unless search_service.use_elasticsearch?
return true if @project
search_service.scope.in?(SWITCH_TO_BASIC_SEARCHABLE_TABS)
end
private private
def search_multiple_assignees?(type) def search_multiple_assignees?(type)
......
# frozen_string_literal: true
module Search
module Elasticsearchable
def use_elasticsearch?
return false if params[:basic_search]
::Gitlab::CurrentSettings.search_using_elasticsearch?(scope: elasticsearchable_scope)
end
def elasticsearchable_scope
raise NotImplementedError
end
end
end
...@@ -5,6 +5,7 @@ module EE ...@@ -5,6 +5,7 @@ module EE
module GlobalService module GlobalService
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
include ::Gitlab::Utils::StrongMemoize include ::Gitlab::Utils::StrongMemoize
include ::Search::Elasticsearchable
override :execute override :execute
def execute def execute
...@@ -19,8 +20,8 @@ module EE ...@@ -19,8 +20,8 @@ module EE
) )
end end
def use_elasticsearch? def elasticsearchable_scope
::Gitlab::CurrentSettings.search_using_elasticsearch?(scope: nil) nil
end end
def elastic_projects def elastic_projects
......
...@@ -5,9 +5,9 @@ module EE ...@@ -5,9 +5,9 @@ module EE
module GroupService module GroupService
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :use_elasticsearch? override :elasticsearchable_scope
def use_elasticsearch? def elasticsearchable_scope
::Gitlab::CurrentSettings.search_using_elasticsearch?(scope: group) group
end end
override :elastic_projects override :elastic_projects
......
...@@ -4,6 +4,7 @@ module EE ...@@ -4,6 +4,7 @@ module EE
module Search module Search
module ProjectService module ProjectService
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
include ::Search::Elasticsearchable
override :execute override :execute
def execute def execute
...@@ -17,9 +18,8 @@ module EE ...@@ -17,9 +18,8 @@ module EE
) )
end end
# This method is used in the top-level SearchService, so cannot be in-lined into #execute def elasticsearchable_scope
def use_elasticsearch? project
::Gitlab::CurrentSettings.search_using_elasticsearch?(scope: project)
end end
end end
end end
......
...@@ -12,9 +12,9 @@ module EE ...@@ -12,9 +12,9 @@ module EE
::Gitlab::Elastic::SnippetSearchResults.new(current_user, params[:search], elastic_projects, nil, true) ::Gitlab::Elastic::SnippetSearchResults.new(current_user, params[:search], elastic_projects, nil, true)
end end
# This method is used in the top-level SearchService, so cannot be in-lined into #execute override :elasticsearchable_scope
def use_elasticsearch? def elasticsearchable_scope
::Gitlab::CurrentSettings.search_using_elasticsearch?(scope: nil) nil
end end
end end
end end
......
- if show_switch_to_basic_search?(search_service)
- begin_link = '<a href="%{url}">'.html_safe % { url: revert_to_basic_search_filter_url }
- end_link = '</a>'.html_safe
%p.text-center
= _('You can try again using %{begin_link}basic search%{end_link}').html_safe % { begin_link: begin_link, end_link: end_link }
...@@ -221,4 +221,33 @@ describe 'Global elastic search', :elastic do ...@@ -221,4 +221,33 @@ describe 'Global elastic search', :elastic do
expect(page).to have_content('Users 0') expect(page).to have_content('Users 0')
end end
end end
context 'when no results are returned' do
it 'allows basic search without Elasticsearch' do
visit dashboard_projects_path
submit_search('project')
# Project won't be found since ES index is not up to date
expect(page).not_to have_content('Projects 1')
# Since there are no results you have the option to instead use basic
# search
click_link 'basic search'
# Project is found now that we are using basic search
expect(page).to have_content('Projects 1')
end
context 'when performing Commits search' do
it 'does not allow basic search' do
visit dashboard_projects_path
submit_search('project')
select_search_scope('Commits')
expect(page).not_to have_link('basic search')
end
end
end
end end
...@@ -175,4 +175,47 @@ describe SearchHelper do ...@@ -175,4 +175,47 @@ describe SearchHelper do
it_behaves_like 'returns old message' it_behaves_like 'returns old message'
end end
end end
describe '#show_switch_to_basic_search?' do
let(:use_elasticsearch) { true }
let(:scope) { 'commits' }
let(:search_service) { instance_double(Search::GlobalService, use_elasticsearch?: use_elasticsearch, scope: scope) }
subject { show_switch_to_basic_search?(search_service) }
before do
stub_feature_flags(switch_to_basic_search: true)
end
context 'when :switch_to_basic_search feature is disabled' do
before do
stub_feature_flags(switch_to_basic_search: false)
end
it { is_expected.to eq(false) }
end
context 'when not currently using elasticsearch' do
let(:use_elasticsearch) { false }
it { is_expected.to eq(false) }
end
context 'when project scope' do
before do
@project = create(:project)
end
it { is_expected.to eq(true) }
end
context 'when commits tab' do
it { is_expected.to eq(false) }
end
context 'when issues tab' do
let(:scope) { 'issues' }
it { is_expected.to eq(true) }
end
end
end end
...@@ -15,7 +15,7 @@ describe Search::GlobalService do ...@@ -15,7 +15,7 @@ describe Search::GlobalService do
it_behaves_like 'EE search service shared examples', ::Gitlab::SearchResults, ::Gitlab::Elastic::SearchResults do it_behaves_like 'EE search service shared examples', ::Gitlab::SearchResults, ::Gitlab::Elastic::SearchResults do
let(:scope) { nil } let(:scope) { nil }
let(:service) { described_class.new(user, search: '*') } let(:service) { described_class.new(user, params) }
end end
context 'visibility', :elastic do context 'visibility', :elastic do
......
...@@ -16,7 +16,7 @@ describe Search::GroupService, :elastic do ...@@ -16,7 +16,7 @@ describe Search::GroupService, :elastic do
it_behaves_like 'EE search service shared examples', ::Gitlab::GroupSearchResults, ::Gitlab::Elastic::GroupSearchResults do it_behaves_like 'EE search service shared examples', ::Gitlab::GroupSearchResults, ::Gitlab::Elastic::GroupSearchResults do
let(:scope) { create(:group) } let(:scope) { create(:group) }
let(:service) { described_class.new(user, scope, search: '*') } let(:service) { described_class.new(user, scope, params) }
end end
describe 'group search' do describe 'group search' do
......
...@@ -14,7 +14,7 @@ describe Search::ProjectService do ...@@ -14,7 +14,7 @@ describe Search::ProjectService do
it_behaves_like 'EE search service shared examples', ::Gitlab::ProjectSearchResults, ::Gitlab::Elastic::ProjectSearchResults do it_behaves_like 'EE search service shared examples', ::Gitlab::ProjectSearchResults, ::Gitlab::Elastic::ProjectSearchResults do
let(:user) { scope.owner } let(:user) { scope.owner }
let(:scope) { create(:project) } let(:scope) { create(:project) }
let(:service) { described_class.new(scope, user, search: '*') } let(:service) { described_class.new(scope, user, params) }
end end
context 'visibility', :elastic do context 'visibility', :elastic do
......
...@@ -6,6 +6,6 @@ describe Search::SnippetService do ...@@ -6,6 +6,6 @@ describe Search::SnippetService do
it_behaves_like 'EE search service shared examples', ::Gitlab::SnippetSearchResults, ::Gitlab::Elastic::SnippetSearchResults do it_behaves_like 'EE search service shared examples', ::Gitlab::SnippetSearchResults, ::Gitlab::Elastic::SnippetSearchResults do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:scope) { nil } let(:scope) { nil }
let(:service) { described_class.new(user, search: '*') } let(:service) { described_class.new(user, params) }
end end
end end
# frozen_string_literal: true # frozen_string_literal: true
RSpec.shared_examples 'EE search service shared examples' do |normal_results, elasticsearch_results| RSpec.shared_examples 'EE search service shared examples' do |normal_results, elasticsearch_results|
let(:params) { { search: '*' } }
describe '#use_elasticsearch?' do describe '#use_elasticsearch?' do
it 'delegates to Gitlab::CurrentSettings.search_using_elasticsearch?' do it 'delegates to Gitlab::CurrentSettings.search_using_elasticsearch?' do
expect(Gitlab::CurrentSettings) expect(Gitlab::CurrentSettings)
...@@ -10,6 +12,17 @@ RSpec.shared_examples 'EE search service shared examples' do |normal_results, el ...@@ -10,6 +12,17 @@ RSpec.shared_examples 'EE search service shared examples' do |normal_results, el
expect(service.use_elasticsearch?).to eq(:value) expect(service.use_elasticsearch?).to eq(:value)
end end
context 'when requesting basic_search' do
let(:params) { { search: '*', basic_search: 'true' } }
it 'returns false' do
expect(Gitlab::CurrentSettings)
.not_to receive(:search_using_elasticsearch?)
expect(service.use_elasticsearch?).to eq(false)
end
end
end end
describe '#execute' do describe '#execute' do
......
...@@ -19209,6 +19209,9 @@ msgstr "" ...@@ -19209,6 +19209,9 @@ msgstr ""
msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}." msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}."
msgstr "" msgstr ""
msgid "You can try again using %{begin_link}basic search%{end_link}"
msgstr ""
msgid "You cannot access the raw file. Please wait a minute." msgid "You cannot access the raw file. Please wait a minute."
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment