don't try indexing non-people
[akkoma] / lib / pleroma / elasticsearch / store.ex
1 defmodule Pleroma.Elasticsearch do
2 alias Pleroma.Activity
3 alias Pleroma.User
4 alias Pleroma.Elasticsearch.DocumentMappings
5 alias Pleroma.Config
6 require Logger
7
8 defp url do
9 Config.get([:elasticsearch, :url])
10 end
11
12 defp enabled? do
13 Config.get([:search, :provider]) == Pleroma.Search.Elasticsearch
14 end
15
16 def put_by_id(:activity, id) do
17 id
18 |> Activity.get_by_id_with_object()
19 |> maybe_put_into_elasticsearch()
20 end
21
22 def maybe_put_into_elasticsearch({:ok, item}) do
23 maybe_put_into_elasticsearch(item)
24 end
25
26 def maybe_put_into_elasticsearch(
27 %{data: %{"type" => "Create"}, object: %{data: %{"type" => "Note"}}} = activity
28 ) do
29 if enabled?() do
30 actor = Pleroma.Activity.user_actor(activity)
31
32 activity
33 |> Map.put(:user_actor, actor)
34 |> put()
35 end
36 end
37
38 def maybe_put_into_elasticsearch(%User{actor_type: "Person"} = user) do
39 if enabled?() do
40 put(user)
41 end
42 end
43
44 def maybe_put_into_elasticsearch(_) do
45 {:ok, :skipped}
46 end
47
48 def put(%Activity{} = activity) do
49 {:ok, _} =
50 Elastix.Document.index(
51 url(),
52 "activities",
53 "activity",
54 DocumentMappings.Activity.id(activity),
55 DocumentMappings.Activity.encode(activity)
56 )
57
58 {:ok, _} =
59 bulk_post(
60 activity.object.hashtags,
61 :hashtags
62 )
63 end
64
65 def put(%User{} = user) do
66 {:ok, _} =
67 Elastix.Document.index(
68 url(),
69 "users",
70 "user",
71 DocumentMappings.User.id(user),
72 DocumentMappings.User.encode(user)
73 )
74 end
75
76 def bulk_post(data, :activities) do
77 d =
78 data
79 |> Enum.filter(fn x ->
80 t =
81 x.object
82 |> Map.get(:data, %{})
83 |> Map.get("type", "")
84
85 t == "Note"
86 end)
87 |> Enum.map(fn d ->
88 [
89 %{index: %{_id: DocumentMappings.Activity.id(d)}},
90 DocumentMappings.Activity.encode(d)
91 ]
92 end)
93 |> List.flatten()
94
95 {:ok, %{body: %{"errors" => false}}} =
96 Elastix.Bulk.post(
97 url(),
98 d,
99 index: "activities",
100 type: "activity"
101 )
102 end
103
104 def bulk_post(data, :users) do
105 d =
106 data
107 |> Enum.map(fn d ->
108 [
109 %{index: %{_id: DocumentMappings.User.id(d)}},
110 DocumentMappings.User.encode(d)
111 ]
112 end)
113 |> List.flatten()
114
115 Elastix.Bulk.post(
116 url(),
117 d,
118 index: "users",
119 type: "user"
120 )
121 end
122
123 def bulk_post([] = data, :hashtags) do
124 d =
125 data
126 |> Enum.map(fn d ->
127 [
128 %{index: %{_id: DocumentMappings.Hashtag.id(d)}},
129 DocumentMappings.Hashtag.encode(d)
130 ]
131 end)
132 |> List.flatten()
133
134 Elastix.Bulk.post(
135 url(),
136 d,
137 index: "hashtags",
138 type: "hashtag"
139 )
140 end
141
142 def bulk_post(_, :hashtags), do: {:ok, nil}
143
144 def search(_, _, _, :skip), do: []
145
146 def search(:raw, index, type, q) do
147 with {:ok, raw_results} <- Elastix.Search.search(url(), index, [type], q) do
148 results =
149 raw_results
150 |> Map.get(:body, %{})
151 |> Map.get("hits", %{})
152 |> Map.get("hits", [])
153
154 {:ok, results}
155 else
156 {:error, e} ->
157 Logger.error(e)
158 {:error, e}
159 end
160 end
161
162 def search(:activities, q) do
163 with {:ok, results} <- search(:raw, "activities", "activity", q) do
164 results
165 |> Enum.map(fn result -> result["_id"] end)
166 |> Pleroma.Activity.all_by_ids_with_object()
167 |> Enum.sort(&(&1.inserted_at >= &2.inserted_at))
168 else
169 e ->
170 Logger.error(e)
171 []
172 end
173 end
174
175 def search(:users, q) do
176 with {:ok, results} <- search(:raw, "users", "user", q) do
177 results
178 |> Enum.map(fn result -> result["_id"] end)
179 |> Pleroma.User.get_all_by_ids()
180 else
181 e ->
182 Logger.error(e)
183 []
184 end
185 end
186
187 def search(:hashtags, q) do
188 with {:ok, results} <- search(:raw, "hashtags", "hashtag", q) do
189 results
190 |> Enum.map(fn result -> result["_source"]["hashtag"] end)
191 else
192 e ->
193 Logger.error(e)
194 []
195 end
196 end
197 end