FIX: Move emotion /filter logic into a CTE to keep cardinality sane (#915)

This commit is contained in:
Rafael dos Santos Silva 2024-11-14 17:16:48 -03:00 committed by GitHub
parent 5026ab52d0
commit 4fb686a548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 29 deletions

View File

@ -46,27 +46,36 @@ module DiscourseAi
END END
)::float / COUNT(posts.id) )::float / COUNT(posts.id)
SQL SQL
scope
.joins(:posts) # TODO: This is slow, we will need to materialize this in the future
.joins(<<~SQL) with_clause = <<~SQL
INNER JOIN classification_results SELECT
ON classification_results.target_id = posts.id topics.id,
AND classification_results.target_type = 'Post' #{emotion_clause} AS emotion_#{emotion}
AND classification_results.model_used = 'SamLowe/roberta-base-go_emotions' FROM
SQL topics
.where(<<~SQL) INNER JOIN
posts ON posts.topic_id = topics.id
INNER JOIN
classification_results ON
classification_results.target_id = posts.id AND
classification_results.target_type = 'Post' AND
classification_results.model_used = 'SamLowe/roberta-base-go_emotions'
WHERE
topics.archetype = 'regular' topics.archetype = 'regular'
AND topics.deleted_at IS NULL AND topics.deleted_at IS NULL
AND posts.deleted_at IS NULL AND posts.deleted_at IS NULL
AND posts.post_type = 1 AND posts.post_type = 1
GROUP BY
1
HAVING
#{emotion_clause} > 0.05
SQL SQL
.select(<<~SQL)
topics.*, scope
#{emotion_clause} AS emotion_#{emotion} .with(topic_emotion: Arel.sql(with_clause))
SQL .joins("INNER JOIN topic_emotion ON topic_emotion.id = topics.id")
.group("1") .order("topic_emotion.emotion_#{emotion} #{order_direction}")
.having("#{emotion_clause} > 0.05")
.order("#{emotion_clause} #{order_direction}")
end end
plugin.add_filter_custom_filter("order:emotion_#{emotion}", &filter_order_emotion) plugin.add_filter_custom_filter("order:emotion_#{emotion}", &filter_order_emotion)
end end

View File

@ -181,14 +181,11 @@ RSpec.describe DiscourseAi::Sentiment::EmotionFilterOrder do
.first .first
result = filter.call(scope, order_direction) result = filter.call(scope, order_direction)
expect(result.to_sql).to include("INNER JOIN classification_results") expect(result.to_sql).to include("classification_results")
expect(result.to_sql).to include( expect(result.to_sql).to include(
"classification_results.model_used = 'SamLowe/roberta-base-go_emotions'", "classification_results.model_used = 'SamLowe/roberta-base-go_emotions'",
) )
expect(result.to_sql).to include("topics.archetype = 'regular'") expect(result.to_sql).to include("ORDER BY topic_emotion.emotion_joy desc")
expect(result.to_sql).to include("ORDER BY")
expect(result.to_sql).to include("->'#{emotion}'")
expect(result.to_sql).to include("desc")
end end
it "sorts emotion in ascending order" do it "sorts emotion in ascending order" do