Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 4fb686a

Browse files
authored
FIX: Move emotion /filter logic into a CTE to keep cardinality sane (#915)
1 parent 5026ab5 commit 4fb686a

File tree

2 files changed

+35
-29
lines changed

2 files changed

+35
-29
lines changed

lib/sentiment/emotion_filter_order.rb

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,34 +39,43 @@ def self.register!(plugin)
3939
filter_order_emotion = ->(scope, order_direction) do
4040
emotion_clause = <<~SQL
4141
SUM(
42-
CASE
43-
WHEN (classification_results.classification::jsonb->'#{emotion}')::float > 0.1
44-
THEN 1
45-
ELSE 0
42+
CASE
43+
WHEN (classification_results.classification::jsonb->'#{emotion}')::float > 0.1
44+
THEN 1
45+
ELSE 0
4646
END
4747
)::float / COUNT(posts.id)
4848
SQL
49+
50+
# TODO: This is slow, we will need to materialize this in the future
51+
with_clause = <<~SQL
52+
SELECT
53+
topics.id,
54+
#{emotion_clause} AS emotion_#{emotion}
55+
FROM
56+
topics
57+
INNER JOIN
58+
posts ON posts.topic_id = topics.id
59+
INNER JOIN
60+
classification_results ON
61+
classification_results.target_id = posts.id AND
62+
classification_results.target_type = 'Post' AND
63+
classification_results.model_used = 'SamLowe/roberta-base-go_emotions'
64+
WHERE
65+
topics.archetype = 'regular'
66+
AND topics.deleted_at IS NULL
67+
AND posts.deleted_at IS NULL
68+
AND posts.post_type = 1
69+
GROUP BY
70+
1
71+
HAVING
72+
#{emotion_clause} > 0.05
73+
SQL
74+
4975
scope
50-
.joins(:posts)
51-
.joins(<<~SQL)
52-
INNER JOIN classification_results
53-
ON classification_results.target_id = posts.id
54-
AND classification_results.target_type = 'Post'
55-
AND classification_results.model_used = 'SamLowe/roberta-base-go_emotions'
56-
SQL
57-
.where(<<~SQL)
58-
topics.archetype = 'regular'
59-
AND topics.deleted_at IS NULL
60-
AND posts.deleted_at IS NULL
61-
AND posts.post_type = 1
62-
SQL
63-
.select(<<~SQL)
64-
topics.*,
65-
#{emotion_clause} AS emotion_#{emotion}
66-
SQL
67-
.group("1")
68-
.having("#{emotion_clause} > 0.05")
69-
.order("#{emotion_clause} #{order_direction}")
76+
.with(topic_emotion: Arel.sql(with_clause))
77+
.joins("INNER JOIN topic_emotion ON topic_emotion.id = topics.id")
78+
.order("topic_emotion.emotion_#{emotion} #{order_direction}")
7079
end
7180
plugin.add_filter_custom_filter("order:emotion_#{emotion}", &filter_order_emotion)
7281
end

spec/lib/modules/sentiment/emotion_filter_order_spec.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,11 @@
181181
.first
182182
result = filter.call(scope, order_direction)
183183

184-
expect(result.to_sql).to include("INNER JOIN classification_results")
184+
expect(result.to_sql).to include("classification_results")
185185
expect(result.to_sql).to include(
186186
"classification_results.model_used = 'SamLowe/roberta-base-go_emotions'",
187187
)
188-
expect(result.to_sql).to include("topics.archetype = 'regular'")
189-
expect(result.to_sql).to include("ORDER BY")
190-
expect(result.to_sql).to include("->'#{emotion}'")
191-
expect(result.to_sql).to include("desc")
188+
expect(result.to_sql).to include("ORDER BY topic_emotion.emotion_joy desc")
192189
end
193190

194191
it "sorts emotion in ascending order" do

0 commit comments

Comments
 (0)