@@ -137,27 +137,48 @@ export async function fetchMembersForEnrichment(
137137 SELECT 1 FROM "memberEnrichmentCache" mec
138138 WHERE mec."memberId" = members.id
139139 AND mec.source = '${ input . source } '
140- AND EXTRACT(EPOCH FROM ( now() - mec."updatedAt")) < ${ input . cacheObsoleteAfterSeconds } )
140+ AND mec."updatedAt" > now() - make_interval(secs => ${ input . cacheObsoleteAfterSeconds } ) )
141141 )` ,
142142 )
143143 }
144144
145145 enrichableBySqlConditions . push ( `(${ input . enrichableBySql } )` )
146146 } )
147147
148- let enrichableBySqlJoined = ''
149-
150- if ( enrichableBySqlConditions . length > 0 ) {
151- enrichableBySqlJoined = `(${ enrichableBySqlConditions . join ( ' OR ' ) } ) `
152- }
148+ const enrichableBySqlJoined =
149+ enrichableBySqlConditions . length > 0 ? `(${ enrichableBySqlConditions . join ( ' OR ' ) } )` : 'TRUE'
153150
151+ // Pick top-N by activity first, then load identities for those rows only.
154152 return db . connection ( ) . query (
155153 `
154+ WITH candidates AS (
155+ SELECT
156+ members.id,
157+ members."displayName",
158+ members.attributes->'location'->>'default' AS location,
159+ members.attributes->'websiteUrl'->>'default' AS website,
160+ coalesce("membersGlobalActivityCount".total_count, 0) AS "activityCount"
161+ FROM "membersGlobalActivityCount"
162+ INNER JOIN members ON members.id = "membersGlobalActivityCount"."memberId"
163+ WHERE members."deletedAt" IS NULL
164+ AND coalesce((members.attributes ->'isBot'->>'default')::boolean, false) = false
165+ AND coalesce((members.attributes ->'isOrganization'->>'default')::boolean, false) = false
166+ AND EXISTS (
167+ SELECT 1
168+ FROM "memberIdentities" mi
169+ WHERE mi."memberId" = members.id
170+ AND mi."deletedAt" IS NULL
171+ AND ${ enrichableBySqlJoined }
172+ )
173+ AND (${ cacheAgeInnerQueryItems . join ( ' OR ' ) } )
174+ ORDER BY "membersGlobalActivityCount".total_count DESC
175+ LIMIT $1
176+ )
156177 SELECT
157- members."id" ,
158- members ."displayName",
159- members.attributes->'location'->>'default' AS location,
160- members.attributes->'websiteUrl'->>'default' AS website,
178+ c.id ,
179+ c ."displayName",
180+ c. location,
181+ c. website,
161182 JSON_AGG(
162183 JSON_BUILD_OBJECT(
163184 'platform', mi.platform,
@@ -166,19 +187,18 @@ export async function fetchMembersForEnrichment(
166187 'verified', mi.verified
167188 )
168189 ) AS identities,
169- MAX(coalesce("membersGlobalActivityCount".total_count, 0)) AS "activityCount"
170- FROM members
171- INNER JOIN "memberIdentities" mi ON mi."memberId" = members.id and mi."deletedAt" is null
172- LEFT JOIN "membersGlobalActivityCount" ON "membersGlobalActivityCount"."memberId" = members.id
173- WHERE
174- ${ enrichableBySqlJoined }
175- AND coalesce((members.attributes ->'isBot'->>'default')::boolean, false) = false
176- AND coalesce((members.attributes ->'isOrganization'->>'default')::boolean, false) = false
177- AND members."deletedAt" IS NULL
178- AND (${ cacheAgeInnerQueryItems . join ( ' OR ' ) } )
179- GROUP BY members.id
180- ORDER BY "activityCount" DESC
181- LIMIT $1;
190+ c."activityCount"
191+ FROM candidates c
192+ INNER JOIN members ON members.id = c.id
193+ INNER JOIN "memberIdentities" mi
194+ ON mi."memberId" = c.id
195+ AND mi."deletedAt" IS NULL
196+ CROSS JOIN LATERAL (
197+ SELECT c."activityCount" AS total_count
198+ ) AS "membersGlobalActivityCount"
199+ WHERE ${ enrichableBySqlJoined }
200+ GROUP BY c.id, c."displayName", c.location, c.website, c."activityCount"
201+ ORDER BY c."activityCount" DESC;
182202 ` ,
183203 [ limit ] ,
184204 )
0 commit comments