feat(search): use postgres native fulltext search
All checks were successful
Build / build (push) Successful in 3m46s
All checks were successful
Build / build (push) Successful in 3m46s
This commit is contained in:
parent
5397833935
commit
d40db4ca4c
3 changed files with 67 additions and 12 deletions
|
@ -46,8 +46,6 @@ defmodule BdfrBrowser.Comment do
|
|||
def search(str), do: search(str, nil)
|
||||
|
||||
def search(str, subreddits) when is_nil(subreddits) do
|
||||
search_str = "%#{str}%"
|
||||
|
||||
from(c in __MODULE__,
|
||||
join: p in assoc(c, :post),
|
||||
join: s in assoc(p, :subreddit),
|
||||
|
@ -62,15 +60,15 @@ defmodule BdfrBrowser.Comment do
|
|||
post_title: p.title,
|
||||
post_date: fragment("to_char(?, 'YYYY-MM')", p.posted_at)
|
||||
},
|
||||
where: ilike(c.body, ^search_str),
|
||||
where:
|
||||
fragment("? @@ websearch_to_tsquery('english', ?)", c.searchable_content, ^str) or
|
||||
fragment("? @@ websearch_to_tsquery('german', ?)", c.searchable_content, ^str),
|
||||
order_by: [desc: c.posted_at],
|
||||
group_by: [c.id, p.id, s.name]
|
||||
)
|
||||
end
|
||||
|
||||
def search(str, subreddits) when is_list(subreddits) do
|
||||
search_str = "%#{str}%"
|
||||
|
||||
from(c in __MODULE__,
|
||||
join: p in assoc(c, :post),
|
||||
join: s in assoc(p, :subreddit),
|
||||
|
@ -85,7 +83,10 @@ defmodule BdfrBrowser.Comment do
|
|||
post_title: p.title,
|
||||
post_date: fragment("to_char(?, 'YYYY-MM')", p.posted_at)
|
||||
},
|
||||
where: s.name in ^subreddits and ilike(c.body, ^search_str),
|
||||
where:
|
||||
s.name in ^subreddits and
|
||||
(fragment("? @@ websearch_to_tsquery('english', ?)", c.searchable_content, ^str) or
|
||||
fragment("? @@ websearch_to_tsquery('german', ?)", c.searchable_content, ^str)),
|
||||
order_by: [desc: c.posted_at],
|
||||
group_by: [c.id, p.id, s.name]
|
||||
)
|
||||
|
|
|
@ -123,8 +123,6 @@ defmodule BdfrBrowser.Post do
|
|||
def search(str), do: search(str, nil)
|
||||
|
||||
def search(str, subreddits) when is_nil(subreddits) do
|
||||
search_str = "%#{str}%"
|
||||
|
||||
from(p in __MODULE__,
|
||||
left_join: c in assoc(p, :comments),
|
||||
join: s in assoc(p, :subreddit),
|
||||
|
@ -137,15 +135,15 @@ defmodule BdfrBrowser.Post do
|
|||
subreddit: s.name,
|
||||
date: fragment("to_char(?, 'YYYY-MM')", p.posted_at)
|
||||
},
|
||||
where: ilike(p.title, ^search_str) or ilike(p.selftext, ^search_str),
|
||||
where:
|
||||
fragment("? @@ websearch_to_tsquery('english', ?)", p.searchable_content, ^str) or
|
||||
fragment("? @@ websearch_to_tsquery('german', ?)", p.searchable_content, ^str),
|
||||
order_by: [desc: p.posted_at],
|
||||
group_by: [p.id, s.name]
|
||||
)
|
||||
end
|
||||
|
||||
def search(str, subreddits) when is_list(subreddits) do
|
||||
search_str = "%#{str}%"
|
||||
|
||||
from(p in __MODULE__,
|
||||
left_join: c in assoc(p, :comments),
|
||||
join: s in assoc(p, :subreddit),
|
||||
|
@ -158,7 +156,10 @@ defmodule BdfrBrowser.Post do
|
|||
subreddit: s.name,
|
||||
date: fragment("to_char(?, 'YYYY-MM')", p.posted_at)
|
||||
},
|
||||
where: s.name in ^subreddits and (ilike(p.title, ^search_str) or ilike(p.selftext, ^search_str)),
|
||||
where:
|
||||
s.name in ^subreddits and
|
||||
(fragment("? @@ websearch_to_tsquery('english', ?)", p.searchable_content, ^str) or
|
||||
fragment("? @@ websearch_to_tsquery('german', ?)", p.searchable_content, ^str)),
|
||||
order_by: [desc: p.posted_at],
|
||||
group_by: [p.id, s.name]
|
||||
)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
defmodule BdfrBrowser.Repo.Migrations.AddPostCommentFulltextSearch do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
# Posts
|
||||
execute """
|
||||
ALTER TABLE posts
|
||||
ADD COLUMN searchable_content tsvector
|
||||
GENERATED ALWAYS AS (
|
||||
setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
|
||||
setweight(to_tsvector('german', coalesce(title, '')), 'A') ||
|
||||
setweight(to_tsvector('english', coalesce(selftext, '')), 'B') ||
|
||||
setweight(to_tsvector('german', coalesce(selftext, '')), 'B') ||
|
||||
setweight(to_tsvector('simple', coalesce(author, '')), 'C')
|
||||
) STORED;
|
||||
"""
|
||||
|
||||
execute """
|
||||
CREATE INDEX posts_searchable_content_index ON posts USING gin(searchable_content);
|
||||
"""
|
||||
|
||||
# Comments
|
||||
execute """
|
||||
ALTER TABLE comments
|
||||
ADD COLUMN searchable_content tsvector
|
||||
GENERATED ALWAYS AS (
|
||||
setweight(to_tsvector('english', coalesce(body, '')), 'A') ||
|
||||
setweight(to_tsvector('german', coalesce(body, '')), 'A') ||
|
||||
setweight(to_tsvector('simple', coalesce(author, '')), 'B')
|
||||
) STORED;
|
||||
"""
|
||||
|
||||
execute """
|
||||
CREATE INDEX comments_searchable_content_index ON comments USING gin(searchable_content);
|
||||
"""
|
||||
end
|
||||
|
||||
def down do
|
||||
# Posts
|
||||
drop index("posts", [:searchable_content])
|
||||
|
||||
alter table(:posts) do
|
||||
remove :searchable_content
|
||||
end
|
||||
|
||||
# Comments
|
||||
drop index("comments", [:searchable_content])
|
||||
|
||||
alter table(:comments) do
|
||||
remove :searchable_content
|
||||
end
|
||||
end
|
||||
end
|
Reference in a new issue