X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fsearch%2Felasticsearch.ex;h=20e03e1f0d7c40b6a7e1c44c54fd05cccb7c038f;hb=3f76de76dac266ea2909dbd1dc88a9533d972952;hp=eabd2a8521a3fd56c27858c0be438c93f2bf33d4;hpb=d1bb10c88e151f837f3b875f13304e6439925b87;p=akkoma diff --git a/lib/pleroma/search/elasticsearch.ex b/lib/pleroma/search/elasticsearch.ex index eabd2a852..20e03e1f0 100644 --- a/lib/pleroma/search/elasticsearch.ex +++ b/lib/pleroma/search/elasticsearch.ex @@ -1,125 +1,91 @@ +# Akkoma: A lightweight social networking server +# Copyright © 2022-2022 Akkoma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Search.Elasticsearch do - @behaviour Pleroma.Search + @behaviour Pleroma.Search.SearchBackend - alias Pleroma.Web.MastodonAPI.StatusView - alias Pleroma.Web.MastodonAPI.AccountView + alias Pleroma.Activity + alias Pleroma.Object.Fetcher alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Search.Elasticsearch.Parsers - alias Pleroma.Web.Endpoint - def es_query(:activity, query) do + def es_query(:activity, query, offset, limit) do must = Parsers.Activity.parse(query) - if must == [] do - :skip - else - %{ - size: 50, - terminate_after: 50, - timeout: "5s", - sort: [ - %{"_timestamp" => "desc"} - ], - query: %{ - bool: %{ - must: must - } + %{ + size: limit, + from: offset, + terminate_after: 50, + timeout: "5s", + sort: [ + "_score", + %{"_timestamp" => %{order: "desc", format: "basic_date_time"}} + ], + query: %{ + bool: %{ + must: must } } - end + } end - def es_query(:user, query) do - must = Parsers.User.parse(query) - - if must == [] do - :skip + 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 - %{ - size: 50, - terminate_after: 50, - timeout: "5s", - query: %{ - bool: %{ - must: must - } - } - } + _ -> nil end end - def es_query(:hashtag, query) do - must = Parsers.Hashtag.parse(query) - - if must == [] do - :skip - else - %{ - size: 50, - terminate_after: 50, - timeout: "5s", - query: %{ - bool: %{ - must: Parsers.Hashtag.parse(query) - } - } - } - end - end + def search(user, query, options) do + limit = Enum.min([Keyword.get(options, :limit), 40]) + offset = Keyword.get(options, :offset, 0) - @impl Pleroma.Search - def search(%{assigns: %{user: user}} = _conn, %{q: query} = _params, _options) do parsed_query = query |> String.trim() |> SearchParser.parse!() - activity_task = + activity_fetch_task = Task.async(fn -> - q = es_query(:activity, parsed_query) - - Pleroma.Elasticsearch.search(:activities, q) - |> Enum.filter(fn x -> Visibility.visible_for_user?(x, user) end) + maybe_fetch(:activity, String.trim(query)) end) - user_task = + activity_task = Task.async(fn -> - q = es_query(:user, parsed_query) - - Pleroma.Elasticsearch.search(:users, q) - |> Enum.filter(fn x -> Pleroma.User.visible_for(x, user) == :visible end) + q = es_query(:activity, parsed_query, offset, limit) + + :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) - hashtag_task = - Task.async(fn -> - q = es_query(:hashtag, parsed_query) + activity_results = Task.await(activity_task) + direct_activity = Task.await(activity_fetch_task) - Pleroma.Elasticsearch.search(:hashtags, q) - end) + activity_results = + if direct_activity == nil do + activity_results + else + [direct_activity | activity_results] + end - activity_results = Task.await(activity_task) - user_results = Task.await(user_task) - hashtag_results = Task.await(hashtag_task) + activity_results + end - %{ - "accounts" => - AccountView.render("index.json", - users: user_results, - for: user - ), - "hashtags" => - Enum.map(hashtag_results, fn x -> - %{ - url: Endpoint.url() <> "/tag/" <> x, - name: x - } - end), - "statuses" => - StatusView.render("index.json", - activities: activity_results, - for: user, - as: :activity - ) - } + @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") end end