Commit 5fb33f63 authored by Bob Van Landuyt's avatar Bob Van Landuyt
Browse files

Preload ancestors after pagination when filtering

We need to preload the ancestors of search results after applying
pagination limits. This way the search results itself are paginated,
but not the ancestors.

If we don't do this, we might not preload a parent group of a search
result as it has been cut off by pagination.
parent 0bb3598ccf0a
module GroupTree
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def render_group_tree(groups)
@groups = if params[:filter].present?
# We find the ancestors by ID of the search results here.
# Otherwise the ancestors would also have filters applied,
# which would cause them not to be preloaded.
group_ids = groups.search(params[:filter]).select(:id)
Gitlab::GroupHierarchy.new(Group.where(id: group_ids))
.base_and_ancestors
else
# Only show root groups if no parent-id is given
groups.where(parent_id: params[:parent_id])
end
groups = groups.sort_by_attribute(@sort = params[:sort])
@groups = @groups.with_selects_for_list(archived: params[:archived])
.sort_by_attribute(@sort = params[:sort])
.page(params[:page])
groups = if params[:filter].present?
filtered_groups_with_ancestors(groups)
else
# If `params[:parent_id]` is `nil`, we will only show root-groups
groups.where(parent_id: params[:parent_id]).page(params[:page])
end
@groups = groups.with_selects_for_list(archived: params[:archived])
respond_to do |format|
format.html
......@@ -28,4 +23,21 @@ def render_group_tree(groups)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end
def filtered_groups_with_ancestors(groups)
filtered_groups = groups.search(params[:filter]).page(params[:page])
if Group.supports_nested_groups?
# We find the ancestors by ID of the search results here.
# Otherwise the ancestors would also have filters applied,
# which would cause them not to be preloaded.
#
# Pagination needs to be applied before loading the ancestors to
# make sure ancestors are not cut off by pagination.
Gitlab::GroupHierarchy.new(Group.where(id: filtered_groups.select(:id)))
.base_and_ancestors
else
filtered_groups
end
end
end
......@@ -44,8 +44,8 @@ def expand_hierarchy_for_child(child, hierarchy, hierarchy_top, preloaded)
This error is not user facing, but causes a +1 query.
MSG
extras = {
parent: parent,
child: child,
parent: parent.inspect,
child: child.inspect,
preloaded: preloaded.map(&:full_path)
}
issue_url = 'https://gitlab.com/gitlab-org/gitlab-ce/issues/40785'
......
---
title: Reduce the number of queries when searching for groups
merge_request: 20398
author:
type: performance
......@@ -63,6 +63,17 @@ def index
expect(assigns(:groups)).to contain_exactly(parent, subgroup)
end
it 'preloads parents regardless of pagination' do
allow(Kaminari.config).to receive(:default_per_page).and_return(1)
group = create(:group, :public)
subgroup = create(:group, :public, parent: group)
search_result = create(:group, :public, name: 'result', parent: subgroup)
get :index, filter: 'resu', format: :json
expect(assigns(:groups)).to contain_exactly(group, subgroup, search_result)
end
end
context 'json content' do
......
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