Create the frecent items GraphQL endpoints
What does this MR do and why?
Create the frecent items GraphQL endpoints
Implements the endpoints for fetching frecently visited projects and groups via the GrahphQL API.
Screenshots or screen recordings
No user-facing change.
How to set up and validate locally
-
Enable the
frecent_namespaces_suggestions
feature flag.Feature.enable(:frecent_namespaces_suggestions)
-
(optional) You might want to seed some visits if your GDK hasn't yet tracked enough data. Run the following script in the Rails console to create 1000 project and group visits spread over the last 3 months:
def datetime_rand from = 0.0, to = Time.now Time.at(from + rand * (to.to_f - from.to_f)).to_datetime end def seed_project_visit(user) offset = rand(Project.count) project = Project.offset(offset).first visited_at = datetime_rand Time.now - 3.months Users::ProjectVisit.create!(user_id: user.id, entity_id: project.id, visited_at: visited_at) end def seed_group_visit(user) offset = rand(Group.count) group = Group.offset(offset).first visited_at = datetime_rand Time.now - 3.months Users::GroupVisit.create!(user_id: user.id, entity_id: group.id, visited_at: visited_at) end for i in 1..1000 user = User.first # This should get the root user. Change if needed. seed_project_visit(user) seed_group_visit(user) end
-
In the GraphQL explorer (http://gdk.test:3000/-/graphql-explorer), run any of the following queries to get the frecent projects or groups:
query CurrentUserFrecentProjects { frecentProjects { name webUrl avatarUrl nameWithNamespace } }
query CurrentUserFrecentGroups { frecentGroups { name webUrl avatarUrl fullPath fullName } }
Frecency scores SQL queries
Frecency scores for projects and groups are computed by retrieving a user's project or group visits (effectively limited to the last 3 months due to the tables' retention policy), and adding weighted scores for every namespace. Recent visits score higher.
Both queries output a namespace ID <=> score
list from which we extract the highest scoring entities and retrieve the associated projects/groups:
Project.find(ids)
# or
Group.find(ids)
Projects
SELECT
entity_id,
SUM(week_count * dense_rank) AS score
FROM (
SELECT
"projects_visits"."entity_id",
COUNT(entity_id) AS week_count,
DATE_TRUNC('week', visited_at)::date AS week_start,
DENSE_RANK() OVER (ORDER BY DATE_TRUNC('week', visited_at)::date)
FROM "projects_visits"
WHERE (visited_at > '2023-08-07 16:15:37.939106')
AND (visited_at <= '2023-11-07 16:15:37.954841')
AND "projects_visits"."user_id" = 3732265
GROUP BY "week_start",
"projects_visits"."entity_id") AS ranked_entity_visits
GROUP BY
entity_id
ORDER BY
score DESC
LIMIT 5
Query analysis: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/23700/commands/76119
Groups
SELECT
entity_id,
SUM(week_count * dense_rank) AS score
FROM (
SELECT
"groups_visits"."entity_id",
COUNT(entity_id) AS week_count,
DATE_TRUNC('week', visited_at)::date AS week_start,
DENSE_RANK() OVER (ORDER BY DATE_TRUNC('week', visited_at)::date)
FROM "groups_visits"
WHERE (visited_at > '2023-08-07 16:19:30.014123')
AND (visited_at <= '2023-11-07 16:19:30.014382')
AND "groups_visits"."user_id" = 3732265
GROUP BY "week_start",
"groups_visits"."entity_id") AS ranked_entity_visits
GROUP BY
entity_id
ORDER BY
score DESC
LIMIT 3
Query analysis: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/23700/commands/76120
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #431044 (closed)