Support for user search via PGroonga
This commit is contained in:
parent
01bdebb03f
commit
35be52eb9f
3 changed files with 62 additions and 3 deletions
|
@ -370,6 +370,7 @@ def run(["set_pgroonga_options", pg_options]) do
|
||||||
if pgroonga_enabled do
|
if pgroonga_enabled do
|
||||||
shell_info("Recreate index with options #{pg_options}")
|
shell_info("Recreate index with options #{pg_options}")
|
||||||
Ecto.Adapters.SQL.query!(Pleroma.Repo, "DROP INDEX IF EXISTS object_content_pgroonga;")
|
Ecto.Adapters.SQL.query!(Pleroma.Repo, "DROP INDEX IF EXISTS object_content_pgroonga;")
|
||||||
|
Ecto.Adapters.SQL.query!(Pleroma.Repo, "DROP INDEX IF EXISTS nickname_name_pgroonga;")
|
||||||
|
|
||||||
Ecto.Adapters.SQL.query!(
|
Ecto.Adapters.SQL.query!(
|
||||||
Pleroma.Repo,
|
Pleroma.Repo,
|
||||||
|
@ -378,6 +379,13 @@ def run(["set_pgroonga_options", pg_options]) do
|
||||||
timeout: :infinity
|
timeout: :infinity
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Ecto.Adapters.SQL.query!(
|
||||||
|
Pleroma.Repo,
|
||||||
|
"CREATE INDEX nickname_name_pgroonga ON users USING pgroonga ((ARRAY[nickname::text, name::text])) WITH (#{pg_options});",
|
||||||
|
[],
|
||||||
|
timeout: :infinity
|
||||||
|
)
|
||||||
|
|
||||||
shell_info('Done.')
|
shell_info('Done.')
|
||||||
else
|
else
|
||||||
shell_info('PGroonga is not enabled.')
|
shell_info('PGroonga is not enabled.')
|
||||||
|
|
|
@ -12,6 +12,13 @@ defmodule Pleroma.User.Search do
|
||||||
@limit 20
|
@limit 20
|
||||||
|
|
||||||
def search(query_string, opts \\ []) do
|
def search(query_string, opts \\ []) do
|
||||||
|
query_type =
|
||||||
|
if Pleroma.Config.get([:database, :pgroonga_enabled]) do
|
||||||
|
:pgroonga
|
||||||
|
else
|
||||||
|
:gin
|
||||||
|
end
|
||||||
|
|
||||||
resolve = Keyword.get(opts, :resolve, false)
|
resolve = Keyword.get(opts, :resolve, false)
|
||||||
following = Keyword.get(opts, :following, false)
|
following = Keyword.get(opts, :following, false)
|
||||||
result_limit = Keyword.get(opts, :limit, @limit)
|
result_limit = Keyword.get(opts, :limit, @limit)
|
||||||
|
@ -32,7 +39,7 @@ def search(query_string, opts \\ []) do
|
||||||
|
|
||||||
results =
|
results =
|
||||||
query_string
|
query_string
|
||||||
|> search_query(for_user, following, top_user_ids)
|
|> search_query(query_type, for_user, following, top_user_ids)
|
||||||
|> Pagination.fetch_paginated(%{"offset" => offset, "limit" => result_limit}, :offset)
|
|> Pagination.fetch_paginated(%{"offset" => offset, "limit" => result_limit}, :offset)
|
||||||
|
|
||||||
results
|
results
|
||||||
|
@ -85,14 +92,14 @@ defp format_query(query_string) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp search_query(query_string, for_user, following, top_user_ids) do
|
defp search_query(query_string, query_type, for_user, following, top_user_ids) do
|
||||||
for_user
|
for_user
|
||||||
|> base_query(following)
|
|> base_query(following)
|
||||||
|> filter_blocked_user(for_user)
|
|> filter_blocked_user(for_user)
|
||||||
|> filter_invisible_users()
|
|> filter_invisible_users()
|
||||||
|> filter_internal_users()
|
|> filter_internal_users()
|
||||||
|> filter_blocked_domains(for_user)
|
|> filter_blocked_domains(for_user)
|
||||||
|> fts_search(query_string)
|
|> query_with(query_type, query_string)
|
||||||
|> select_top_users(top_user_ids)
|
|> select_top_users(top_user_ids)
|
||||||
|> trigram_rank(query_string)
|
|> trigram_rank(query_string)
|
||||||
|> boost_search_rank(for_user, top_user_ids)
|
|> boost_search_rank(for_user, top_user_ids)
|
||||||
|
@ -108,6 +115,14 @@ defp select_top_users(query, top_user_ids) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp query_with(query, :gin, query_string) do
|
||||||
|
fts_search(query, query_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp query_with(query, :pgroonga, query_string) do
|
||||||
|
pgroonga_search(query, query_string)
|
||||||
|
end
|
||||||
|
|
||||||
defp fts_search(query, query_string) do
|
defp fts_search(query, query_string) do
|
||||||
query_string = to_tsquery(query_string)
|
query_string = to_tsquery(query_string)
|
||||||
|
|
||||||
|
@ -160,6 +175,26 @@ defp trigram_rank(query, query_string) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp pgroonga_search(query, query_string) do
|
||||||
|
from(
|
||||||
|
u in query,
|
||||||
|
where:
|
||||||
|
fragment(
|
||||||
|
"""
|
||||||
|
ARRAY[?::text, ?::text]
|
||||||
|
&@~ (
|
||||||
|
?,
|
||||||
|
ARRAY[2, 1],
|
||||||
|
'nickname_name_pgroonga'
|
||||||
|
)::pgroonga_full_text_search_condition
|
||||||
|
""",
|
||||||
|
u.nickname,
|
||||||
|
u.name,
|
||||||
|
^query_string
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
defp base_query(%User{} = user, true), do: User.get_friends_query(user)
|
defp base_query(%User{} = user, true), do: User.get_friends_query(user)
|
||||||
defp base_query(_user, _following), do: User
|
defp base_query(_user, _following), do: User
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.CreatePgroongaUserIndex do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
create_if_not_exists(
|
||||||
|
index(:users, ["(ARRAY[nickname::text, name::text])"],
|
||||||
|
using: :pgroonga,
|
||||||
|
name: :nickname_name_pgroonga
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
execute("DROP INDEX IF EXISTS nickname_name_pgroonga")
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue