akkoma/lib/pleroma/elasticsearch/store.ex
2021-12-12 17:35:35 +00:00

120 lines
2.3 KiB
Elixir

defmodule Pleroma.Elasticsearch do
alias Pleroma.Activity
alias Pleroma.Elasticsearch.DocumentMappings
@searchable [
"hashtag", "instance", "user"
]
defp url do
Pleroma.Config.get([:elasticsearch, :url])
end
def put(%Activity{} = activity) do
Elastix.Document.index(
url(),
"activities",
"activity",
DocumentMappings.Activity.id(activity),
DocumentMappings.Activity.encode(activity)
)
end
def bulk_post(data, :activities) do
d = data
|> Enum.map(fn d ->
[
%{index: %{_id: DocumentMappings.Activity.id(d)}},
DocumentMappings.Activity.encode(d)
]
end)
|> List.flatten()
Elastix.Bulk.post(
url(),
d,
index: "activities",
type: "activity"
)
end
defp parse_term(t) do
if String.contains?(t, ":") and !String.starts_with?(t, "\"") do
[field, query] = String.split(t, ":")
if Enum.member?(@searchable, field) do
{field, query}
else
{"content", query}
end
else
{"content", t}
end
end
defp search_user(params, q) do
if q["user"] != nil do
params ++ [%{match: %{user: %{
query: Enum.join(q["user"], " "),
operator: "OR"
}}}]
else
params
end
end
defp search_instance(params, q) do
if q["instance"] != nil do
params ++ [%{match: %{instance: %{
query: Enum.join(q["instance"], " "),
operator: "OR"
}}}]
else
params
end
end
defp search_content(params, q) do
if q["content"] != nil do
params ++ [%{match: %{content: %{
query: Enum.join(q["content"], " "),
operator: "AND"
}}}]
else
params
end
end
defp to_es(q) do
[]
|> search_content(q)
|> search_instance(q)
|> search_user(q)
end
defp parse(query) do
String.split(query, " ")
|> Enum.map(&parse_term/1)
|> Enum.reduce(%{}, fn {field, query}, acc ->
Map.put(acc, field,
Map.get(acc, field, []) ++ [query]
)
end)
|> to_es()
end
def search(query) do
q = %{query: %{
bool: %{
must: parse(query)
}
}}
IO.inspect(q)
Elastix.Search.search(
url(),
"activities",
["activity"],
q
)
end
end