55c459801fe7bd1bba97a6c112bc16d0d886964a
[akkoma] / lib / pleroma / elasticsearch / store.ex
1 defmodule Pleroma.Elasticsearch do
2 alias Pleroma.Activity
3 alias Pleroma.Elasticsearch.DocumentMappings
4
5 @searchable [
6 "hashtag", "instance", "user"
7 ]
8
9 defp url do
10 Pleroma.Config.get([:elasticsearch, :url])
11 end
12
13 def put(%Activity{} = activity) do
14 Elastix.Document.index(
15 url(),
16 "activities",
17 "activity",
18 DocumentMappings.Activity.id(activity),
19 DocumentMappings.Activity.encode(activity)
20 )
21 end
22
23 def bulk_post(data, :activities) do
24 d = data
25 |> Enum.map(fn d ->
26 [
27 %{index: %{_id: DocumentMappings.Activity.id(d)}},
28 DocumentMappings.Activity.encode(d)
29 ]
30 end)
31 |> List.flatten()
32
33 Elastix.Bulk.post(
34 url(),
35 d,
36 index: "activities",
37 type: "activity"
38 )
39 end
40
41 defp parse_term(t) do
42 if String.contains?(t, ":") and !String.starts_with?(t, "\"") do
43 [field, query] = String.split(t, ":")
44 if Enum.member?(@searchable, field) do
45 {field, query}
46 else
47 {"content", query}
48 end
49 else
50 {"content", t}
51 end
52 end
53
54 defp search_user(params, q) do
55 if q["user"] != nil do
56 params ++ [%{match: %{user: %{
57 query: Enum.join(q["user"], " "),
58 operator: "OR"
59 }}}]
60 else
61 params
62 end
63 end
64
65 defp search_instance(params, q) do
66 if q["instance"] != nil do
67 params ++ [%{match: %{instance: %{
68 query: Enum.join(q["instance"], " "),
69 operator: "OR"
70 }}}]
71 else
72 params
73 end
74 end
75
76 defp search_content(params, q) do
77 if q["content"] != nil do
78 params ++ [%{match: %{content: %{
79 query: Enum.join(q["content"], " "),
80 operator: "AND"
81 }}}]
82 else
83 params
84 end
85 end
86
87 defp to_es(q) do
88 []
89 |> search_content(q)
90 |> search_instance(q)
91 |> search_user(q)
92 end
93
94 defp parse(query) do
95 String.split(query, " ")
96 |> Enum.map(&parse_term/1)
97 |> Enum.reduce(%{}, fn {field, query}, acc ->
98 Map.put(acc, field,
99 Map.get(acc, field, []) ++ [query]
100 )
101 end)
102 |> to_es()
103 end
104
105 def search(query) do
106 q = %{query: %{
107 bool: %{
108 must: parse(query)
109 }
110 }}
111 IO.inspect(q)
112 Elastix.Search.search(
113 url(),
114 "activities",
115 ["activity"],
116 q
117 )
118 end
119 end