Move gluing search results from application to database and get mutuals

a higher score multiplier
This commit is contained in:
rinpatch 2019-03-21 23:16:32 +03:00
parent b92a16aa00
commit 88096c65a5
1 changed files with 39 additions and 44 deletions

View File

@ -823,31 +823,53 @@ def search(query, resolve \\ false, for_user \\ nil) do
if resolve, do: get_or_fetch(query) if resolve, do: get_or_fetch(query)
fts_results = do_search(fts_search_subquery(query), for_user) {:ok, results} =
{:ok, trigram_results} =
Repo.transaction(fn -> Repo.transaction(fn ->
Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", []) Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
do_search(trigram_search_subquery(query), for_user) Repo.all(search_query(query, for_user))
end) end)
Enum.uniq_by(fts_results ++ trigram_results, & &1.id) results
end end
defp do_search(subquery, for_user, options \\ []) do def search_query(query, for_user) do
q = fts_subquery = fts_search_subquery(query)
from( trigram_subquery = trigram_search_subquery(query)
s in subquery(subquery), union_query = from(s in trigram_subquery, union: ^fts_subquery)
order_by: [desc: s.search_rank], distinct_query = from(s in subquery(union_query), distinct: s.id)
limit: ^(options[:limit] || 20)
)
results = from(s in subquery(boost_search_rank_query(distinct_query, for_user)),
q order_by: [desc: s.search_rank],
|> Repo.all() limit: 20
|> Enum.filter(&(&1.search_rank > 0)) )
end
boost_search_results(results, for_user) defp boost_search_rank_query(query, nil), do: query
defp boost_search_rank_query(query, for_user) do
friends_ids = get_friends_ids(for_user)
followers_ids = get_followers_ids(for_user)
from(u in subquery(query),
select_merge: %{
search_rank:
fragment(
"""
CASE WHEN (?) THEN (?) * 1.3
WHEN (?) THEN (?) * 1.2
WHEN (?) THEN (?) * 1.1
ELSE (?) END
""",
u.id in ^friends_ids and u.id in ^followers_ids,
u.search_rank,
u.id in ^friends_ids,
u.search_rank,
u.id in ^followers_ids,
u.search_rank,
u.search_rank
)
}
)
end end
defp fts_search_subquery(term, query \\ User) do defp fts_search_subquery(term, query \\ User) do
@ -906,33 +928,6 @@ defp trigram_search_subquery(term) do
) )
end end
defp boost_search_results(results, nil), do: results
defp boost_search_results(results, for_user) do
friends_ids = get_friends_ids(for_user)
followers_ids = get_followers_ids(for_user)
Enum.map(
results,
fn u ->
search_rank_coef =
cond do
u.id in friends_ids ->
1.2
u.id in followers_ids ->
1.1
true ->
1
end
Map.put(u, :search_rank, u.search_rank * search_rank_coef)
end
)
|> Enum.sort_by(&(-&1.search_rank))
end
def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do
Enum.map( Enum.map(
blocked_identifiers, blocked_identifiers,