Skip to content

Add sorting support to organization projects GraphQL query

Abdul Wadood requested to merge 409312-graphql-projects-sort into master

What does this MR do and why?

This is part of the ongoing Organization work by the grouptenant scale group. Read the blueprint to learn more https://docs.gitlab.com/ee/architecture/blueprints/organization/index.html.

The following sorting options are supported:

  1. storage_size_desc
  2. latest_activity_desc
  3. latest_activity_asc
  4. path_asc
  5. path_desc
  6. stars_desc
  7. stars_asc
  8. created_asc
  9. created_at_asc
  10. created_date
  11. created_desc
  12. created_at_desc
  13. id_asc
  14. id_desc
  15. name_asc
  16. name_desc
  17. updated_asc
  18. updated_at_asc
  19. updated_desc
  20. updated_at_desc

Query plans

https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25596/commands/80926

Raw Query
SELECT "projects"."id",
       "projects"."name",
       "projects"."path",
       "projects"."description",
       "projects"."created_at",
       "projects"."updated_at",
       "projects"."creator_id",
       "projects"."namespace_id",
       "projects"."last_activity_at",
       "projects"."import_url",
       "projects"."visibility_level",
       "projects"."archived",
       "projects"."avatar",
       "projects"."merge_requests_template",
       "projects"."star_count",
       "projects"."merge_requests_rebase_enabled",
       "projects"."import_type",
       "projects"."import_source",
       "projects"."approvals_before_merge",
       "projects"."reset_approvals_on_push",
       "projects"."merge_requests_ff_only_enabled",
       "projects"."issues_template",
       "projects"."mirror",
       "projects"."mirror_last_update_at",
       "projects"."mirror_last_successful_update_at",
       "projects"."mirror_user_id",
       "projects"."shared_runners_enabled",
       "projects"."runners_token",
       "projects"."build_allow_git_fetch",
       "projects"."build_timeout",
       "projects"."mirror_trigger_builds",
       "projects"."pending_delete",
       "projects"."public_builds",
       "projects"."last_repository_check_failed",
       "projects"."last_repository_check_at",
       "projects"."only_allow_merge_if_pipeline_succeeds",
       "projects"."has_external_issue_tracker",
       "projects"."repository_storage",
       "projects"."repository_read_only",
       "projects"."request_access_enabled",
       "projects"."has_external_wiki",
       "projects"."ci_config_path",
       "projects"."lfs_enabled",
       "projects"."description_html",
       "projects"."only_allow_merge_if_all_discussions_are_resolved",
       "projects"."repository_size_limit",
       "projects"."printing_merge_request_link_enabled",
       "projects"."auto_cancel_pending_pipelines",
       "projects"."service_desk_enabled",
       "projects"."cached_markdown_version",
       "projects"."delete_error",
       "projects"."last_repository_updated_at",
       "projects"."disable_overriding_approvers_per_merge_request",
       "projects"."storage_version",
       "projects"."resolve_outdated_diff_discussions",
       "projects"."remote_mirror_available_overridden",
       "projects"."only_mirror_protected_branches",
       "projects"."pull_mirror_available_overridden",
       "projects"."jobs_cache_index",
       "projects"."external_authorization_classification_label",
       "projects"."mirror_overwrites_diverged_branches",
       "projects"."pages_https_only",
       "projects"."external_webhook_token",
       "projects"."packages_enabled",
       "projects"."merge_requests_author_approval",
       "projects"."pool_repository_id",
       "projects"."runners_token_encrypted",
       "projects"."bfg_object_map",
       "projects"."detected_repository_languages",
       "projects"."merge_requests_disable_committers_approval",
       "projects"."require_password_to_approve",
       "projects"."max_pages_size",
       "projects"."max_artifacts_size",
       "projects"."pull_mirror_branch_prefix",
       "projects"."remove_source_branch_after_merge",
       "projects"."marked_for_deletion_at",
       "projects"."marked_for_deletion_by_user_id",
       "projects"."autoclose_referenced_issues",
       "projects"."suggestion_commit_message",
       "projects"."project_namespace_id",
       "projects"."hidden",
       "projects"."organization_id"
FROM "projects"
WHERE (EXISTS (SELECT 1
               FROM "project_authorizations"
               WHERE "project_authorizations"."user_id" = 10327656
                 AND (project_authorizations.project_id = projects.id)) OR projects.visibility_level IN (10, 20))
  AND "projects"."pending_delete" = FALSE
  AND "projects"."organization_id" = 1
  AND "projects"."hidden" = FALSE
ORDER BY "projects"."path" ASC, "projects"."id" DESC
LIMIT 101;

https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25683/commands/81087

Raw Query
SELECT "projects"."id",
       "projects"."name",
       "projects"."path",
       "projects"."description",
       "projects"."created_at",
       "projects"."updated_at",
       "projects"."creator_id",
       "projects"."namespace_id",
       "projects"."last_activity_at",
       "projects"."import_url",
       "projects"."visibility_level",
       "projects"."archived",
       "projects"."avatar",
       "projects"."merge_requests_template",
       "projects"."star_count",
       "projects"."merge_requests_rebase_enabled",
       "projects"."import_type",
       "projects"."import_source",
       "projects"."approvals_before_merge",
       "projects"."reset_approvals_on_push",
       "projects"."merge_requests_ff_only_enabled",
       "projects"."issues_template",
       "projects"."mirror",
       "projects"."mirror_last_update_at",
       "projects"."mirror_last_successful_update_at",
       "projects"."mirror_user_id",
       "projects"."shared_runners_enabled",
       "projects"."runners_token",
       "projects"."build_allow_git_fetch",
       "projects"."build_timeout",
       "projects"."mirror_trigger_builds",
       "projects"."pending_delete",
       "projects"."public_builds",
       "projects"."last_repository_check_failed",
       "projects"."last_repository_check_at",
       "projects"."only_allow_merge_if_pipeline_succeeds",
       "projects"."has_external_issue_tracker",
       "projects"."repository_storage",
       "projects"."repository_read_only",
       "projects"."request_access_enabled",
       "projects"."has_external_wiki",
       "projects"."ci_config_path",
       "projects"."lfs_enabled",
       "projects"."description_html",
       "projects"."only_allow_merge_if_all_discussions_are_resolved",
       "projects"."repository_size_limit",
       "projects"."printing_merge_request_link_enabled",
       "projects"."auto_cancel_pending_pipelines",
       "projects"."service_desk_enabled",
       "projects"."cached_markdown_version",
       "projects"."delete_error",
       "projects"."last_repository_updated_at",
       "projects"."disable_overriding_approvers_per_merge_request",
       "projects"."storage_version",
       "projects"."resolve_outdated_diff_discussions",
       "projects"."remote_mirror_available_overridden",
       "projects"."only_mirror_protected_branches",
       "projects"."pull_mirror_available_overridden",
       "projects"."jobs_cache_index",
       "projects"."external_authorization_classification_label",
       "projects"."mirror_overwrites_diverged_branches",
       "projects"."pages_https_only",
       "projects"."external_webhook_token",
       "projects"."packages_enabled",
       "projects"."merge_requests_author_approval",
       "projects"."pool_repository_id",
       "projects"."runners_token_encrypted",
       "projects"."bfg_object_map",
       "projects"."detected_repository_languages",
       "projects"."merge_requests_disable_committers_approval",
       "projects"."require_password_to_approve",
       "projects"."max_pages_size",
       "projects"."max_artifacts_size",
       "projects"."pull_mirror_branch_prefix",
       "projects"."remove_source_branch_after_merge",
       "projects"."marked_for_deletion_at",
       "projects"."marked_for_deletion_by_user_id",
       "projects"."autoclose_referenced_issues",
       "projects"."suggestion_commit_message",
       "projects"."project_namespace_id",
       "projects"."hidden",
       "projects"."organization_id"
FROM "projects"
WHERE (EXISTS (SELECT 1
               FROM "project_authorizations"
               WHERE "project_authorizations"."user_id" = 10327656
                 AND (project_authorizations.project_id = projects.id)) OR projects.visibility_level IN (10, 20))
  AND "projects"."pending_delete" = FALSE
  AND "projects"."organization_id" = 1
  AND "projects"."hidden" = FALSE
ORDER BY "projects"."path" DESC, "projects"."id" DESC
LIMIT 10;

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

How to set up and validate locally

Run the following query on https://gdk.test:3000/-/graphql-explorer and change sort options to sort the projects in different order:

{
  organization(id: "gid://gitlab/Organizations::Organization/1") {
    id
    projects(sort: "path_desc") {
      nodes {
        id
        path
      }
    } 
  }
}

Related to #409312 (closed)

Edited by Abdul Wadood

Merge request reports