···
9
-
Did string `ch:"did"`
10
-
TheirLikes uint64 `ch:"their_likes"`
11
-
MyLikes uint64 `ch:"my_likes"`
12
-
TheirReplies uint64 `ch:"their_replies"`
13
-
MyReplies uint64 `ch:"my_replies"`
14
-
FriendConnectionScore float64 `ch:"friend_connection_score"`
15
-
ClosenessScore float64 `ch:"closeness_score"`
16
-
InteractionType string `ch:"interaction_type"`
9
+
SuggestedDid string `ch:"suggested_did"`
10
+
BskyUrl string `ch:"bsky_url"`
11
+
InteractionScore uint64 `ch:"interaction_score"`
12
+
InteractedByCount uint64 `ch:"interacted_by_count"`
13
+
ConnectionType string `ch:"connection_type"`
14
+
BlendedScore uint64 `ch:"blended_score"`
18
+
CloseByExistingConnectionWeight = 1
19
+
NewDiscoveryWeight = 1
20
+
TopMutualLimit = 500
func (u *User) getCloseBy(ctx context.Context, s *Server) ([]CloseBy, error) {
// TODO: this "if you have more than 10" feels a little bit too low?
if !time.Now().After(u.closeByExpiresAt) && len(u.following) > 10 {
···
33
-
if err := s.conn.Select(ctx, &closeBy, getCloseByQuery, u.did); err != nil {
37
+
if err := s.conn.Select(ctx, &closeBy, getCloseByQuery, u.did, CloseByExistingConnectionWeight, NewDiscoveryWeight, TopMutualLimit); err != nil {
···
48
+
now() - interval 14 day AS timeframe,
49
+
? as existing_connection_weight,
50
+
? as new_discovery_weight,
51
+
? as top_mutual_limit
47
-
all_dids.did AS did,
48
-
coalesce(likes.their_likes, 0) AS their_likes,
49
-
coalesce(likes.my_likes, 0) AS my_likes,
50
-
coalesce(replies.their_replies, 0) AS their_replies,
51
-
coalesce(replies.my_replies, 0) AS my_replies,
52
-
coalesce(friends.friend_connection_score, 0) AS friend_connection_score,
54
-
(coalesce(likes.their_likes, 0) + coalesce(likes.my_likes, 0)) * 1.0 +
55
-
(coalesce(replies.their_replies, 0) + coalesce(replies.my_replies, 0)) * 2.0 +
56
-
coalesce(friends.friend_connection_score, 0) AS closeness_score,
59
-
coalesce(likes.their_likes, 0) > 0 AND coalesce(likes.my_likes, 0) > 0, 'mutual_likes',
60
-
coalesce(replies.their_replies, 0) > 0 AND coalesce(replies.my_replies, 0) > 0, 'mutual_replies',
61
-
coalesce(likes.my_likes, 0) > 0 OR coalesce(replies.my_replies, 0) > 0, 'one_way_from_me',
62
-
coalesce(likes.their_likes, 0) > 0 OR coalesce(replies.their_replies, 0) > 0, 'one_way_to_me',
63
-
coalesce(friends.friend_connection_score, 0) > 0, 'friend_of_friends',
65
-
) AS interaction_type
69
-
SELECT subject_did AS did FROM default.interaction WHERE did = my_did AND kind = 'like'
71
-
SELECT did FROM default.interaction WHERE subject_did = my_did AND kind = 'like'
73
-
SELECT parent_did AS did FROM default.post WHERE did = my_did AND parent_did IS NOT NULL
75
-
SELECT did FROM default.post WHERE parent_did = my_did
77
-
SELECT i.subject_did AS did
78
-
FROM default.interaction i
79
-
WHERE i.kind = 'like'
80
-
AND i.subject_did != my_did
84
-
coalesce(top_l.did, top_r.did) AS did,
85
-
(coalesce(top_l.their_likes, 0) + coalesce(top_l.my_likes, 0)) * 1.0 +
86
-
(coalesce(top_r.their_replies, 0) + coalesce(top_r.my_replies, 0)) * 2.0 AS friend_score
93
-
SELECT did AS them, count(*) AS their_likes
94
-
FROM default.interaction
95
-
WHERE subject_did = my_did AND kind = 'like'
99
-
SELECT subject_did AS them, count(*) as my_likes
100
-
FROM default.interaction
101
-
WHERE did = my_did AND kind = 'like'
102
-
GROUP BY subject_did
103
-
) AS il ON lm.them = il.them
107
-
replies_to_you.them AS did,
108
-
replies_to_you.their_replies,
109
-
replies_to_them.my_replies
111
-
SELECT did AS them, count(*) AS their_replies
113
-
WHERE parent_did = my_did
115
-
) AS replies_to_you
117
-
SELECT parent_did AS them, count(*) AS my_replies
120
-
GROUP BY parent_did
121
-
) AS replies_to_them ON replies_to_you.them = replies_to_them.them
122
-
) AS top_r ON top_l.did = top_r.did
123
-
ORDER BY friend_score DESC
54
+
i.subject_did as suggested_did,
55
+
concat('https://bsky.app/profile/', suggested_did) as bsky_url,
56
+
COUNT(*) as interaction_score,
57
+
COUNT(DISTINCT i.did) as interacted_by_count,
59
+
WHEN i.subject_did IN (
60
+
SELECT subject_did FROM interaction WHERE did = your_did AND created_at > timeframe
62
+
SELECT subject FROM follow WHERE did = your_did
127
-
AND i.subject_did NOT IN (
128
-
SELECT subject_did FROM default.interaction WHERE did = my_did
130
-
SELECT did FROM default.interaction WHERE subject_did = my_did
132
-
SELECT parent_did FROM default.post WHERE did = my_did AND parent_did IS NOT NULL
134
-
SELECT did FROM default.post WHERE parent_did = my_did
136
-
GROUP BY i.subject_did
137
-
HAVING count(*) >= 3
144
-
sum(their_likes) as their_likes,
145
-
sum(my_likes) as my_likes
148
-
subject_did AS did,
150
-
count(*) as my_likes
151
-
FROM default.interaction
152
-
WHERE did = my_did AND kind = 'like'
153
-
GROUP BY subject_did
159
-
count(*) AS their_likes,
161
-
FROM default.interaction
162
-
WHERE subject_did = my_did AND kind = 'like'
166
-
) AS likes ON all_dids.did = likes.did
171
-
sum(their_replies) as their_replies,
172
-
sum(my_replies) as my_replies
176
-
0 as their_replies,
177
-
count(*) AS my_replies
179
-
WHERE did = my_did AND parent_did IS NOT NULL
180
-
GROUP BY parent_did
186
-
count(*) AS their_replies,
189
-
WHERE parent_did = my_did
193
-
) AS replies ON all_dids.did = replies.did
197
-
i.subject_did AS did,
198
-
count(*) * 0.3 AS friend_connection_score
199
-
FROM default.interaction i
200
-
WHERE i.kind = 'like'
201
-
AND i.subject_did != my_did
64
+
THEN 'existing_connection'
65
+
ELSE 'new_discovery'
66
+
END as connection_type,
68
+
WHEN i.subject_did IN (
69
+
SELECT subject_did FROM interaction WHERE did = your_did AND created_at > timeframe
71
+
SELECT subject FROM follow WHERE did = your_did
73
+
THEN existing_connection_weight
74
+
ELSE new_discovery_weight
75
+
END as blended_score
79
+
AND i.created_at > timeframe
80
+
AND i.subject_did != your_did
205
-
coalesce(top_l.did, top_r.did) AS did,
206
-
(coalesce(top_l.their_likes, 0) + coalesce(top_l.my_likes, 0)) * 1.0 +
207
-
(coalesce(top_r.their_replies, 0) + coalesce(top_r.my_replies, 0)) * 2.0 AS friend_score
214
-
SELECT did AS them, count(*) AS their_likes
215
-
FROM default.interaction
216
-
WHERE subject_did = my_did AND kind = 'like'
220
-
SELECT subject_did AS them, count(*) as my_likes
221
-
FROM default.interaction
222
-
WHERE did = my_did AND kind = 'like'
223
-
GROUP BY subject_did
224
-
) AS il ON lm.them = il.them
228
-
replies_to_you.them AS did,
229
-
replies_to_you.their_replies,
230
-
replies_to_them.my_replies
232
-
SELECT did AS them, count(*) AS their_replies
234
-
WHERE parent_did = my_did
236
-
) AS replies_to_you
238
-
SELECT parent_did AS them, count(*) AS my_replies
241
-
GROUP BY parent_did
242
-
) AS replies_to_them ON replies_to_you.them = replies_to_them.them
243
-
) AS top_r ON top_l.did = top_r.did
244
-
ORDER BY friend_score DESC
82
+
SELECT i1.subject_did
84
+
INNER JOIN interaction_reverse i2 ON (
85
+
i1.subject_did = i2.did
86
+
AND i2.subject_did = your_did
87
+
AND i2.kind = 'like'
88
+
AND i1.created_at > timeframe
92
+
AND i1.kind = 'like'
93
+
AND i1.created_at > timeframe
94
+
GROUP BY i1.subject_did
95
+
ORDER BY COUNT(*) DESC
96
+
LIMIT top_mutual_limit
248
-
AND i.subject_did NOT IN (
249
-
SELECT subject_did FROM default.interaction WHERE did = my_did
251
-
SELECT did FROM default.interaction WHERE subject_did = my_did
253
-
SELECT parent_did FROM default.post WHERE did = my_did AND parent_did IS NOT NULL
255
-
SELECT did FROM default.post WHERE parent_did = my_did
257
-
GROUP BY i.subject_did
258
-
HAVING count(*) >= 3
259
-
) AS friends ON all_dids.did = friends.did
261
-
WHERE all_dids.did IS NOT NULL
262
-
ORDER BY closeness_score DESC
98
+
GROUP BY i.subject_did
99
+
ORDER BY blended_score DESC