X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Felasticsearch%2Fstore.ex;h=7f6ef37a927ad46dcbbbe4e36761c5b66e1b0e54;hb=415d9dd6f6887af96d85cfb2c306b94bb8a1a42f;hp=55c459801fe7bd1bba97a6c112bc16d0d886964a;hpb=345eb7b3f8bd241132fc414e20e4f1649d359df7;p=akkoma diff --git a/lib/pleroma/elasticsearch/store.ex b/lib/pleroma/elasticsearch/store.ex index 55c459801..7f6ef37a9 100644 --- a/lib/pleroma/elasticsearch/store.ex +++ b/lib/pleroma/elasticsearch/store.ex @@ -1,119 +1,206 @@ defmodule Pleroma.Elasticsearch do alias Pleroma.Activity + alias Pleroma.User + alias Pleroma.Object alias Pleroma.Elasticsearch.DocumentMappings - - @searchable [ - "hashtag", "instance", "user" - ] + alias Pleroma.Config + require Logger defp url do - Pleroma.Config.get([:elasticsearch, :url]) + Config.get([:elasticsearch, :url]) + end + + defp enabled? do + Config.get([:search, :provider]) == Pleroma.Search.Elasticsearch + end + + def put_by_id(:activity, id) do + id + |> Activity.get_by_id_with_object() + |> maybe_put_into_elasticsearch() + end + + def maybe_put_into_elasticsearch({:ok, item}) do + maybe_put_into_elasticsearch(item) + end + + def maybe_put_into_elasticsearch( + %{data: %{"type" => "Create"}, object: %{data: %{"type" => "Note"}}} = activity + ) do + if enabled?() do + actor = Pleroma.Activity.user_actor(activity) + + activity + |> Map.put(:user_actor, actor) + |> put() + end + end + + def maybe_put_into_elasticsearch(%User{actor_type: "Person"} = user) do + if enabled?() do + put(user) + end + end + + def maybe_put_into_elasticsearch(_) do + {:ok, :skipped} + end + + def maybe_bulk_post(data, type) do + if enabled?() do + bulk_post(data, type) + end end def put(%Activity{} = activity) do - Elastix.Document.index( + {:ok, _} = + Elastix.Document.index( url(), "activities", "activity", DocumentMappings.Activity.id(activity), DocumentMappings.Activity.encode(activity) - ) + ) + + activity + |> Map.get(:object) + |> Object.hashtags() + |> Enum.map(fn x -> %{id: x, name: x, timestamp: DateTime.to_iso8601(DateTime.utc_now())} end) + |> bulk_post(:hashtags) + end + + def put(%User{} = user) do + {:ok, _} = + Elastix.Document.index( + url(), + "users", + "user", + DocumentMappings.User.id(user), + DocumentMappings.User.encode(user) + ) end def bulk_post(data, :activities) do - d = data - |> Enum.map(fn d -> + d = + data + |> Enum.filter(fn x -> + t = + x.object + |> Map.get(:data, %{}) + |> Map.get("type", "") + + t == "Note" + end) + |> Enum.map(fn d -> [ - %{index: %{_id: DocumentMappings.Activity.id(d)}}, - DocumentMappings.Activity.encode(d) + %{index: %{_id: DocumentMappings.Activity.id(d)}}, + DocumentMappings.Activity.encode(d) ] - end) - |> List.flatten() + end) + |> List.flatten() - Elastix.Bulk.post( + {:ok, %{body: %{"errors" => false}}} = + Elastix.Bulk.post( url(), d, index: "activities", type: "activity" + ) + end + + + def bulk_post(data, :users) do + d = + data + |> Enum.filter(fn x -> x.actor_type == "Person" end) + |> Enum.map(fn d -> + [ + %{index: %{_id: DocumentMappings.User.id(d)}}, + DocumentMappings.User.encode(d) + ] + end) + |> List.flatten() + + Elastix.Bulk.post( + url(), + d, + index: "users", + type: "user" ) 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 + def bulk_post(data, :hashtags) when is_list(data) do + d = + data + |> Enum.map(fn d -> + [ + %{index: %{_id: DocumentMappings.Hashtag.id(d)}}, + DocumentMappings.Hashtag.encode(d) + ] + end) + |> List.flatten() + + Elastix.Bulk.post( + url(), + d, + index: "hashtags", + type: "hashtag" + ) + end + + def bulk_post(_, :hashtags), do: {:ok, nil} + + def search(_, _, _, :skip), do: [] + + def search(:raw, index, type, q) do + with {:ok, raw_results} <- Elastix.Search.search(url(), index, [type], q) do + results = + raw_results + |> Map.get(:body, %{}) + |> Map.get("hits", %{}) + |> Map.get("hits", []) + + {:ok, results} else - {"content", t} + {:error, e} -> + Logger.error(e) + {:error, e} end end - defp search_user(params, q) do - if q["user"] != nil do - params ++ [%{match: %{user: %{ - query: Enum.join(q["user"], " "), - operator: "OR" - }}}] + def search(:activities, q) do + with {:ok, results} <- search(:raw, "activities", "activity", q) do + results + |> Enum.map(fn result -> result["_id"] end) + |> Pleroma.Activity.all_by_ids_with_object() + |> Enum.sort(&(&1.inserted_at >= &2.inserted_at)) else - params + e -> + Logger.error(e) + [] end end - defp search_instance(params, q) do - if q["instance"] != nil do - params ++ [%{match: %{instance: %{ - query: Enum.join(q["instance"], " "), - operator: "OR" - }}}] + def search(:users, q) do + with {:ok, results} <- search(:raw, "users", "user", q) do + results + |> Enum.map(fn result -> result["_id"] end) + |> Pleroma.User.get_all_by_ids() else - params + e -> + Logger.error(e) + [] end end - defp search_content(params, q) do - if q["content"] != nil do - params ++ [%{match: %{content: %{ - query: Enum.join(q["content"], " "), - operator: "AND" - }}}] + def search(:hashtags, q) do + with {:ok, results} <- search(:raw, "hashtags", "hashtag", q) do + results + |> Enum.map(fn result -> result["_source"]["hashtag"] end) else - params + e -> + Logger.error(e) + [] 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