# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
- require Logger
require Pleroma.Constants
import Mix.Pleroma
import Ecto.Query
- import Pleroma.Search.Meilisearch, only: [meili_post!: 2, meili_delete!: 1, meili_get!: 1]
+ import Pleroma.Search.Meilisearch,
+ only: [meili_put: 2, meili_get: 1, meili_delete!: 1]
def run(["index"]) do
start_pleroma()
- meili_post!(
- "/indexes/objects/settings/ranking-rules",
- [
- "desc(published)",
- "typo",
- "words",
- "proximity",
- "attribute",
- "wordsPosition",
- "exactness"
- ]
- )
+ meili_version =
+ (
+ {:ok, result} = meili_get("/version")
- meili_post!(
- "/indexes/objects/settings/searchable-attributes",
- [
- "content"
- ]
- )
+ result["pkgVersion"]
+ )
+
+ # The ranking rule syntax was changed but nothing about that is mentioned in the changelog
+ if not Version.match?(meili_version, ">= 0.25.0") do
+ raise "Meilisearch <0.24.0 not supported"
+ end
+
+ {:ok, _} =
+ meili_put(
+ "/indexes/objects/settings/ranking-rules",
+ [
+ "published:desc",
+ "words",
+ "exactness",
+ "proximity",
+ "typo",
+ "attribute",
+ "sort"
+ ]
+ )
+
+ {:ok, _} =
+ meili_put(
+ "/indexes/objects/settings/searchable-attributes",
+ [
+ "content"
+ ]
+ )
+
+ IO.puts("Created indices. Starting to insert posts.")
- chunk_size = 10_000
+ chunk_size = Pleroma.Config.get([Pleroma.Search.Meilisearch, :initial_indexing_chunk_size])
Pleroma.Repo.transaction(
fn ->
query =
from(Pleroma.Object,
- # Only index public posts which are notes and have some text
+ # Only index public and unlisted posts which are notes and have some text
where:
fragment("data->>'type' = 'Note'") and
- fragment("LENGTH(data->>'content') > 0") and
- fragment("data->'to' \\? ?", ^Pleroma.Constants.as_public()),
+ (fragment("data->'to' \\? ?", ^Pleroma.Constants.as_public()) or
+ fragment("data->'cc' \\? ?", ^Pleroma.Constants.as_public())),
order_by: [desc: fragment("data->'published'")]
)
end)
|> Stream.each(fn objects ->
result =
- meili_post!(
+ meili_put(
"/indexes/objects/documents",
objects
)
- if not Map.has_key?(result, "updateId") do
- IO.puts("Failed to index: #{inspect(result)}")
+ with {:ok, res} <- result do
+ if not Map.has_key?(res, "indexUid") do
+ IO.puts("\nFailed to index: #{inspect(result)}")
+ end
+ else
+ e -> IO.puts("\nFailed to index due to network error: #{inspect(e)}")
end
end)
|> Stream.run()
meili_delete!("/indexes/objects/documents")
end
- def run(["show-private-key", master_key]) do
+ def run(["show-keys", master_key]) do
start_pleroma()
endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
{:ok, result} =
Pleroma.HTTP.get(
Path.join(endpoint, "/keys"),
- [{"X-Meili-API-Key", master_key}]
+ [{"Authorization", "Bearer #{master_key}"}]
)
decoded = Jason.decode!(result.body)
- if decoded["private"] do
- IO.puts(decoded["private"])
+ if decoded["results"] do
+ Enum.each(decoded["results"], fn %{"description" => desc, "key" => key} ->
+ IO.puts("#{desc}: #{key}")
+ end)
else
- IO.puts("Error fetching the key, check the master key is correct: #{inspect(decoded)}")
+ IO.puts("Error fetching the keys, check the master key is correct: #{inspect(decoded)}")
end
end
def run(["stats"]) do
start_pleroma()
- result = meili_get!("/indexes/objects/stats")
+ {:ok, result} = meili_get("/indexes/objects/stats")
IO.puts("Number of entries: #{result["numberOfDocuments"]}")
IO.puts("Indexing? #{result["isIndexing"]}")
end