| 3 |
"query": "WITH q AS (\n SELECT websearch_to_tsquery('english', $1) AS tsq\n ),\n thread_matches AS (\n SELECT t.id AS thread_id,\n t.title AS thread_title,\n COALESCE(u.display_name, u.username) AS author_username,\n co.name AS community_name,\n co.slug AS community_slug,\n c.name AS category_name,\n c.slug AS category_slug,\n LEFT(t.title, 200) AS snippet,\n t.last_activity_at,\n (ts_rank(t.search_tsv, q.tsq) * 2.0\n + similarity(t.title, $2)) AS rank\n FROM threads t\n JOIN categories c ON c.id = t.category_id\n JOIN communities co ON co.id = c.community_id\n JOIN users u ON u.mnw_account_id = t.author_id\n CROSS JOIN q\n WHERE t.deleted_at IS NULL\n AND co.suspended_at IS NULL\n AND (t.search_tsv @@ q.tsq\n OR t.title % $2)\n AND ($3::text IS NULL OR co.slug = $3)\n ),\n post_matches AS (\n SELECT DISTINCT ON (t.id)\n t.id AS thread_id,\n t.title AS thread_title,\n COALESCE(pu.display_name, pu.username) AS author_username,\n co.name AS community_name,\n co.slug AS community_slug,\n c.name AS category_name,\n c.slug AS category_slug,\n LEFT(p.body_markdown, 200) AS snippet,\n t.last_activity_at,\n ts_rank(p.search_tsv, q.tsq) AS rank\n FROM posts p\n JOIN threads t ON t.id = p.thread_id\n JOIN categories c ON c.id = t.category_id\n JOIN communities co ON co.id = c.community_id\n -- Author of the matched *reply* (`p.author_id`), not the thread OP\n -- (`t.author_id`): the snippet is the reply's body, so it must be\n -- attributed to whoever wrote it.\n JOIN users pu ON pu.mnw_account_id = p.author_id\n CROSS JOIN q\n WHERE t.deleted_at IS NULL\n AND co.suspended_at IS NULL\n AND p.removed_at IS NULL\n AND p.search_tsv @@ q.tsq\n AND ($3::text IS NULL OR co.slug = $3)\n AND NOT EXISTS (SELECT 1 FROM thread_matches tm WHERE tm.thread_id = t.id)\n ORDER BY t.id, ts_rank(p.search_tsv, q.tsq) DESC\n )\n SELECT\n thread_id AS \"thread_id!\",\n thread_title AS \"thread_title!\",\n author_username AS \"author_username!\",\n community_name AS \"community_name!\",\n community_slug AS \"community_slug!\",\n category_name AS \"category_name!\",\n category_slug AS \"category_slug!\",\n snippet AS \"snippet!\",\n last_activity_at AS \"last_activity_at!: chrono::DateTime<chrono::Utc>\",\n rank AS \"rank!\"\n FROM (\n SELECT * FROM thread_matches\n UNION ALL\n SELECT * FROM post_matches\n ) results\n ORDER BY rank DESC, last_activity_at DESC\n LIMIT $4", |