Commit 86b54309 authored by Terri Chu's avatar Terri Chu Committed by Dylan Griffith

Enable advanced search by default for global search scope

parent 1d704420
...@@ -168,7 +168,10 @@ If you select `Limit namespaces and projects that can be indexed`, more options ...@@ -168,7 +168,10 @@ If you select `Limit namespaces and projects that can be indexed`, more options
You can select namespaces and projects to index exclusively. Please note that if the namespace is a group it will include You can select namespaces and projects to index exclusively. Please note that if the namespace is a group it will include
any sub-groups and projects belonging to those sub-groups to be indexed as well. any sub-groups and projects belonging to those sub-groups to be indexed as well.
Elasticsearch only provides cross-group code/commit search (global) if all name-spaces are indexed. In this particular scenario where only a subset of namespaces are indexed, a global search will not provide a code or commit scope. This will be possible only in the scope of an indexed namespace. Currently there is no way to code/commit search in multiple indexed namespaces (when only a subset of namespaces has been indexed). For example if two groups are indexed, there is no way to run a single code search on both. You can only run a code search on the first group and then on the second. NOTE: **Note:**
Elasticsearch only provides cross-group [code, commit, comment, and wiki](../user/search/advanced_global_search.md#overview) global search for indexed namespaces.
In this particular scenario where only a subset of namespaces are indexed, a global search will provide code, commit, comment, and wiki scopes which return values from the subset of indexed namespaces. If you would like to perform a search against a namespace that is not indexed, you can select the group or project in the search filter. Additionally, it is possible to perform a global "basic search" by appending `&basic_search=true` to the URL in the browser bar. This search will use other data sources (that is PostgreSQL data and Git data) and the code, commit, comment, and wiki scopes will not be displayed.
You can filter the selection dropdown by writing part of the namespace or project name you're interested in. You can filter the selection dropdown by writing part of the namespace or project name you're interested in.
......
...@@ -239,7 +239,7 @@ module EE ...@@ -239,7 +239,7 @@ module EE
when Project when Project
elasticsearch_indexes_project?(scope) elasticsearch_indexes_project?(scope)
else else
false # Never use elasticsearch for the global scope when limiting is on true # Use elasticsearch for the global scope, even when limiting is on
end end
end end
......
---
title: Enable Advanced Search for global scope searches
merge_request: 38093
author:
type: changed
...@@ -434,7 +434,7 @@ RSpec.describe ApplicationSetting do ...@@ -434,7 +434,7 @@ RSpec.describe ApplicationSetting do
context 'global scope' do context 'global scope' do
let(:scope) { nil } let(:scope) { nil }
it { is_expected.to eq(only_when_enabled_globally) } it { is_expected.to eq(indexing && searching) }
end end
context 'namespace (in scope)' do context 'namespace (in scope)' do
......
...@@ -61,10 +61,7 @@ RSpec.describe API::Search do ...@@ -61,10 +61,7 @@ RSpec.describe API::Search do
shared_examples 'elasticsearch enabled' do |level:| shared_examples 'elasticsearch enabled' do |level:|
context 'for merge_requests scope', :sidekiq_inline do context 'for merge_requests scope', :sidekiq_inline do
before do before do
create(:labeled_merge_request, target_branch: 'feature_1', source_project: project, labels: [create(:label), create(:label)]) create_list(:merge_request, 3, :unique_branches, source_project: project, author: create(:user), milestone: create(:milestone, project: project), labels: [create(:label)])
create(:merge_request, target_branch: 'feature_2', source_project: project, author: create(:user))
create(:merge_request, target_branch: 'feature_3', source_project: project, milestone: create(:milestone, project: project))
create(:merge_request, target_branch: 'feature_4', source_project: project)
ensure_elasticsearch_index! ensure_elasticsearch_index!
end end
...@@ -72,19 +69,14 @@ RSpec.describe API::Search do ...@@ -72,19 +69,14 @@ RSpec.describe API::Search do
it 'avoids N+1 queries' do it 'avoids N+1 queries' do
control = ActiveRecord::QueryRecorder.new { get api(endpoint, user), params: { scope: 'merge_requests', search: '*' } } control = ActiveRecord::QueryRecorder.new { get api(endpoint, user), params: { scope: 'merge_requests', search: '*' } }
create_list(:merge_request, 3, :unique_branches, source_project: project, author: create(:user), milestone: create(:milestone, project: project), labels: [create(:label)])
create(:labeled_merge_request, target_branch: 'feature_5', source_project: project, labels: [create(:label), create(:label)])
create(:merge_request, target_branch: 'feature_6', source_project: project, author: create(:user))
create(:merge_request, target_branch: 'feature_7', source_project: project, milestone: create(:milestone, project: project))
create(:merge_request, target_branch: 'feature_8', source_project: project)
ensure_elasticsearch_index! ensure_elasticsearch_index!
expect { get api(endpoint, user), params: { scope: 'merge_requests', search: '*' } }.not_to exceed_query_limit(control) expect { get api(endpoint, user), params: { scope: 'merge_requests', search: '*' } }.not_to exceed_query_limit(control)
end end
end end
context 'for wiki_blobs scope', :sidekiq_might_not_need_inline do context 'for wiki_blobs scope', :sidekiq_inline do
before do before do
wiki = create(:project_wiki, project: project) wiki = create(:project_wiki, project: project)
create(:wiki_page, wiki: wiki, title: 'home', content: "Awesome page") create(:wiki_page, wiki: wiki, title: 'home', content: "Awesome page")
...@@ -101,71 +93,72 @@ RSpec.describe API::Search do ...@@ -101,71 +93,72 @@ RSpec.describe API::Search do
it_behaves_like 'pagination', scope: 'wiki_blobs' it_behaves_like 'pagination', scope: 'wiki_blobs'
end end
context 'for commits scope', :sidekiq_inline do context 'for commits and blobs', :sidekiq_inline do
before do before do
project.repository.index_commits_and_blobs project.repository.index_commits_and_blobs
ensure_elasticsearch_index! ensure_elasticsearch_index!
get api(endpoint, user), params: { scope: 'commits', search: 'folder' }
end end
it_behaves_like 'response is correct', schema: 'public_api/v4/commits_details', size: 2 context 'for commits scope' do
before do
it_behaves_like 'pagination', scope: 'commits' get api(endpoint, user), params: { scope: 'commits', search: 'folder' }
end
it 'avoids N+1 queries' do it_behaves_like 'response is correct', schema: 'public_api/v4/commits_details', size: 2
control = ActiveRecord::QueryRecorder.new { get api(endpoint, user), params: { scope: 'commits', search: 'folder' } }
project_2 = create(:project, :public, :repository, :wiki_repo, name: 'awesome project 2') it_behaves_like 'pagination', scope: 'commits'
project_3 = create(:project, :public, :repository, :wiki_repo, name: 'awesome project 3')
project_2.repository.index_commits_and_blobs
project_3.repository.index_commits_and_blobs
ensure_elasticsearch_index! it 'avoids N+1 queries' do
control = ActiveRecord::QueryRecorder.new { get api(endpoint, user), params: { scope: 'commits', search: 'folder' } }
# Some N+1 queries still exist project_2 = create(:project, :public, :repository, :wiki_repo, name: 'awesome project 2')
expect { get api(endpoint, user), params: { scope: 'commits', search: 'folder' } }.not_to exceed_query_limit(control).with_threshold(9) project_3 = create(:project, :public, :repository, :wiki_repo, name: 'awesome project 3')
end project_2.repository.index_commits_and_blobs
end project_3.repository.index_commits_and_blobs
context 'for blobs scope', :sidekiq_might_not_need_inline do ensure_elasticsearch_index!
before do
project.repository.index_commits_and_blobs
ensure_elasticsearch_index!
get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' } # Some N+1 queries still exist
expect { get api(endpoint, user), params: { scope: 'commits', search: 'folder' } }.not_to exceed_query_limit(control).with_threshold(9)
end
end end
it_behaves_like 'response is correct', schema: 'public_api/v4/blobs' context 'for blobs scope' do
before do
get api(endpoint, user), params: { scope: 'blobs', search: 'monitors' }
end
it_behaves_like 'pagination', scope: 'blobs' it_behaves_like 'response is correct', schema: 'public_api/v4/blobs'
context 'filters' do it_behaves_like 'pagination', scope: 'blobs'
it 'by filename' do
get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon* filename:PROCESS.md' }
expect(response).to have_gitlab_http_status(:ok) context 'filters' do
expect(json_response.size).to eq(1) it 'by filename' do
expect(json_response.first['path']).to eq('PROCESS.md') get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon* filename:PROCESS.md' }
end
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(1)
expect(json_response.first['path']).to eq('PROCESS.md')
end
it 'by path' do it 'by path' do
get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon* path:markdown' } get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon* path:markdown' }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(1) expect(json_response.size).to eq(1)
json_response.each do |file| json_response.each do |file|
expect(file['path']).to match(%r[/markdown/]) expect(file['path']).to match(%r[/markdown/])
end
end end
end
it 'by extension' do it 'by extension' do
get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon* extension:md' } get api("/projects/#{project.id}/search", user), params: { scope: 'blobs', search: 'mon* extension:md' }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(3) expect(json_response.size).to eq(3)
json_response.each do |file| json_response.each do |file|
expect(file['path']).to match(/\A.+\.md\z/) expect(file['path']).to match(/\A.+\.md\z/)
end
end end
end end
end end
...@@ -236,7 +229,7 @@ RSpec.describe API::Search do ...@@ -236,7 +229,7 @@ RSpec.describe API::Search do
end end
end end
context 'for users scope', :sidekiq_inline do context 'for users scope', :sidekiq_might_not_need_inline do
before do before do
create_list(:user, 2).each do |user| create_list(:user, 2).each do |user|
project.add_developer(user) project.add_developer(user)
...@@ -292,7 +285,13 @@ RSpec.describe API::Search do ...@@ -292,7 +285,13 @@ RSpec.describe API::Search do
stub_ee_application_setting(elasticsearch_limit_indexing: true) stub_ee_application_setting(elasticsearch_limit_indexing: true)
end end
it_behaves_like 'elasticsearch disabled' context 'and namespace is indexed' do
before do
create :elasticsearch_indexed_namespace, namespace: group
end
it_behaves_like 'elasticsearch enabled', level: :global
end
end end
context 'when elasticsearch_limit_indexing off' do context 'when elasticsearch_limit_indexing off' do
......
...@@ -182,8 +182,8 @@ RSpec.describe Search::GlobalService do ...@@ -182,8 +182,8 @@ RSpec.describe Search::GlobalService do
stub_ee_application_setting(elasticsearch_limit_indexing: true) stub_ee_application_setting(elasticsearch_limit_indexing: true)
end end
it 'does not include ES-specific scopes' do it 'includes ES-specific scopes' do
expect(described_class.new(user, {}).allowed_scopes).not_to include('commits') expect(described_class.new(user, {}).allowed_scopes).to include('commits')
end end
end end
end end
......
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