aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/user
diff options
context:
space:
mode:
authorMaksim <parallel588@gmail.com>2019-06-14 11:39:57 +0000
committerlain <lain@soykaf.club>2019-06-14 11:39:57 +0000
commitee4ed87fb47fa6c395e0f77b614f1630f3a12637 (patch)
treef4dbeab1fd2b37b4f722e39e5db9e59c83c148ce /lib/pleroma/user
parentf045d1437cb9e1e53565c4f35be2c7ca3a9d73ff (diff)
downloadpleroma-ee4ed87fb47fa6c395e0f77b614f1630f3a12637.tar.gz
[#948] /api/v1/account_search added optional parameters (limit, offset, following)
Diffstat (limited to 'lib/pleroma/user')
-rw-r--r--lib/pleroma/user/search.ex58
1 files changed, 42 insertions, 16 deletions
diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex
index f88dffa7b..ed06c2ab9 100644
--- a/lib/pleroma/user/search.ex
+++ b/lib/pleroma/user/search.ex
@@ -7,45 +7,69 @@ defmodule Pleroma.User.Search do
alias Pleroma.User
import Ecto.Query
- def search(query, opts \\ []) do
+ @similarity_threshold 0.25
+ @limit 20
+
+ def search(query_string, opts \\ []) do
resolve = Keyword.get(opts, :resolve, false)
+ following = Keyword.get(opts, :following, false)
+ result_limit = Keyword.get(opts, :limit, @limit)
+ offset = Keyword.get(opts, :offset, 0)
+
for_user = Keyword.get(opts, :for_user)
# Strip the beginning @ off if there is a query
- query = String.trim_leading(query, "@")
+ query_string = String.trim_leading(query_string, "@")
- maybe_resolve(resolve, for_user, query)
+ maybe_resolve(resolve, for_user, query_string)
{:ok, results} =
Repo.transaction(fn ->
- Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
+ Ecto.Adapters.SQL.query(
+ Repo,
+ "select set_limit(#{@similarity_threshold})",
+ []
+ )
- query
- |> search_query(for_user)
+ query_string
+ |> search_query(for_user, following)
+ |> paginate(result_limit, offset)
|> Repo.all()
end)
results
end
- defp search_query(query, for_user) do
- query
- |> union_query()
+ defp search_query(query_string, for_user, following) do
+ for_user
+ |> base_query(following)
+ |> search_subqueries(query_string)
+ |> union_subqueries
|> distinct_query()
|> boost_search_rank_query(for_user)
|> subquery()
|> order_by(desc: :search_rank)
- |> limit(20)
|> maybe_restrict_local(for_user)
end
- defp union_query(query) do
- fts_subquery = fts_search_subquery(query)
- trigram_subquery = trigram_search_subquery(query)
+ defp base_query(_user, false), do: User
+ defp base_query(user, true), do: User.get_followers_query(user)
+
+ defp paginate(query, limit, offset) do
+ from(q in query, limit: ^limit, offset: ^offset)
+ end
+ defp union_subqueries({fts_subquery, trigram_subquery}) do
from(s in trigram_subquery, union_all: ^fts_subquery)
end
+ defp search_subqueries(base_query, query_string) do
+ {
+ fts_search_subquery(base_query, query_string),
+ trigram_search_subquery(base_query, query_string)
+ }
+ end
+
defp distinct_query(q) do
from(s in subquery(q), order_by: s.search_type, distinct: s.id)
end
@@ -102,7 +126,8 @@ defmodule Pleroma.User.Search do
)
end
- defp fts_search_subquery(term, query \\ User) do
+ @spec fts_search_subquery(User.t() | Ecto.Query.t(), String.t()) :: Ecto.Query.t()
+ defp fts_search_subquery(query, term) do
processed_query =
term
|> String.replace(~r/\W+/, " ")
@@ -144,9 +169,10 @@ defmodule Pleroma.User.Search do
|> User.restrict_deactivated()
end
- defp trigram_search_subquery(term) do
+ @spec trigram_search_subquery(User.t() | Ecto.Query.t(), String.t()) :: Ecto.Query.t()
+ defp trigram_search_subquery(query, term) do
from(
- u in User,
+ u in query,
select_merge: %{
# ^1 gives 'Postgrex expected a binary, got 1' for some weird reason
search_type: fragment("?", 1),