88 lines
1.7 KiB
Elixir
88 lines
1.7 KiB
Elixir
defmodule Pleroma.Search.Elasticsearch do
|
|
@behaviour Pleroma.Search
|
|
|
|
alias Pleroma.Web.MastodonAPI.StatusView
|
|
alias Pleroma.Web.ActivityPub.Visibility
|
|
|
|
defp to_es(term) when is_binary(term) do
|
|
%{
|
|
match: %{
|
|
content: %{
|
|
query: term,
|
|
operator: "AND"
|
|
}
|
|
}
|
|
}
|
|
end
|
|
|
|
defp to_es({:quoted, term}), do: to_es(term)
|
|
|
|
defp to_es({:filter, ["hashtag", query]}) do
|
|
%{
|
|
term: %{
|
|
hashtags: %{
|
|
value: query
|
|
}
|
|
}
|
|
}
|
|
end
|
|
|
|
defp to_es({:filter, [field, query]}) do
|
|
%{
|
|
term: %{
|
|
field => %{
|
|
value: query
|
|
}
|
|
}
|
|
}
|
|
end
|
|
|
|
defp parse(query) do
|
|
query
|
|
|> SearchParser.parse!()
|
|
|> Enum.map(&to_es/1)
|
|
end
|
|
|
|
@impl Pleroma.Search
|
|
def search(%{assigns: %{user: user}} = _conn, %{q: query} = _params, _options) do
|
|
q = %{
|
|
size: 500,
|
|
terminate_after: 500,
|
|
timeout: "10s",
|
|
sort: [
|
|
%{"_timestamp" => "desc"}
|
|
],
|
|
query: %{
|
|
bool: %{
|
|
must: parse(String.trim(query))
|
|
}
|
|
}
|
|
}
|
|
|
|
out = Pleroma.Elasticsearch.search_activities(q)
|
|
|
|
with {:ok, raw_results} <- out do
|
|
results =
|
|
raw_results
|
|
|> Map.get(:body, %{})
|
|
|> Map.get("hits", %{})
|
|
|> Map.get("hits", [])
|
|
|> Enum.map(fn result -> result["_id"] end)
|
|
|> Pleroma.Activity.all_by_ids_with_object()
|
|
|> Enum.filter(fn x -> Visibility.visible_for_user?(x, user) end)
|
|
|> Enum.reverse()
|
|
|
|
%{
|
|
"accounts" => [],
|
|
"hashtags" => [],
|
|
"statuses" =>
|
|
StatusView.render("index.json",
|
|
activities: results,
|
|
for: user,
|
|
as: :activity
|
|
)
|
|
}
|
|
end
|
|
end
|
|
end
|