akkoma/lib/pleroma/search/elasticsearch.ex

92 lines
2.3 KiB
Elixir
Raw Permalink Normal View History

2022-01-20 12:48:16 +00:00
# Akkoma: A lightweight social networking server
# Copyright © 2022-2022 Akkoma Authors <https://git.ihatebeinga.live/IHBAGang/akkoma/>
# SPDX-License-Identifier: AGPL-3.0-only
2021-12-12 17:23:44 +00:00
defmodule Pleroma.Search.Elasticsearch do
2022-06-30 15:28:31 +00:00
@behaviour Pleroma.Search.SearchBackend
2021-12-12 17:23:44 +00:00
2021-12-15 10:57:47 +00:00
alias Pleroma.Activity
alias Pleroma.Object.Fetcher
2021-12-12 18:25:20 +00:00
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Search.Elasticsearch.Parsers
2021-12-12 17:23:44 +00:00
2022-06-30 15:28:31 +00:00
def es_query(:activity, query, offset, limit) do
2021-12-14 15:02:11 +00:00
must = Parsers.Activity.parse(query)
%{
size: limit,
from: offset,
terminate_after: 50,
timeout: "5s",
sort: [
"_score",
%{"_timestamp" => %{order: "desc", format: "basic_date_time"}}
],
query: %{
bool: %{
must: must
2021-12-12 17:23:44 +00:00
}
}
}
2021-12-12 17:23:44 +00:00
end
2021-12-15 10:57:47 +00:00
defp maybe_fetch(:activity, search_query) do
with true <- Regex.match?(~r/https?:/, search_query),
{:ok, object} <- Fetcher.fetch_object_from_id(search_query),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]) do
activity
else
_ -> nil
end
end
2022-06-30 15:28:31 +00:00
def search(user, query, options) do
limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0)
parsed_query =
query
|> String.trim()
|> SearchParser.parse!()
2021-12-12 17:23:44 +00:00
2021-12-15 10:57:47 +00:00
activity_fetch_task =
Task.async(fn ->
maybe_fetch(:activity, String.trim(query))
end)
activity_task =
Task.async(fn ->
2022-06-30 15:28:31 +00:00
q = es_query(:activity, parsed_query, offset, limit)
2021-12-12 17:23:44 +00:00
:activities
|> Pleroma.Search.Elasticsearch.Store.search(q)
|> Enum.filter(fn x ->
x.data["type"] == "Create" && x.object.data["type"] == "Note" &&
Visibility.visible_for_user?(x, user)
end)
end)
2021-12-12 17:23:44 +00:00
activity_results = Task.await(activity_task)
2021-12-15 10:57:47 +00:00
direct_activity = Task.await(activity_fetch_task)
activity_results =
if direct_activity == nil do
activity_results
else
[direct_activity | activity_results]
end
2022-06-30 15:28:31 +00:00
activity_results
end
@impl true
def add_to_index(activity) do
Elasticsearch.put_document(Pleroma.Search.Elasticsearch.Cluster, activity, "activities")
end
@impl true
def remove_from_index(object) do
Elasticsearch.delete_document(Pleroma.Search.Elasticsearch.Cluster, object, "activities")
2021-12-12 17:23:44 +00:00
end
end