4c0127f0f9a7d44e43f04136429e92f05825f266
[akkoma] / lib / pleroma / search / elasticsearch.ex
1 defmodule Pleroma.Search.Elasticsearch do
2 @behaviour Pleroma.Search
3
4 alias Pleroma.Web.MastodonAPI.StatusView
5 alias Pleroma.Web.ActivityPub.Visibility
6
7 defp to_es(term) when is_binary(term) do
8 %{
9 match: %{
10 content: %{
11 query: term,
12 operator: "AND"
13 }
14 }
15 }
16 end
17
18 defp to_es({:quoted, term}), do: to_es(term)
19
20 defp to_es({:filter, ["hashtag", query]}) do
21 %{
22 term: %{
23 hashtags: %{
24 value: query
25 }
26 }
27 }
28 end
29
30 defp to_es({:filter, [field, query]}) do
31 %{
32 term: %{
33 field => %{
34 value: query
35 }
36 }
37 }
38 end
39
40 defp parse(query) do
41 query
42 |> SearchParser.parse!()
43 |> Enum.map(&to_es/1)
44 end
45
46 @impl Pleroma.Search
47 def search(%{assigns: %{user: user}} = _conn, %{q: query} = _params, _options) do
48 q = %{
49 query: %{
50 bool: %{
51 must: parse(query)
52 }
53 }
54 }
55
56 out = Pleroma.Elasticsearch.search_activities(q)
57
58 with {:ok, raw_results} <- out do
59 results =
60 raw_results
61 |> Map.get(:body, %{})
62 |> Map.get("hits", %{})
63 |> Map.get("hits", [])
64 |> Enum.map(fn result -> result["_id"] end)
65 |> Pleroma.Activity.all_by_ids_with_object()
66 |> Enum.filter(fn x -> Visibility.visible_for_user?(x, user) end)
67
68 %{
69 "accounts" => [],
70 "hashtags" => [],
71 "statuses" =>
72 StatusView.render("index.json",
73 activities: results,
74 for: user,
75 as: :activity
76 )
77 }
78 end
79 end
80 end