Fix ParadeDB key field handling
Use uuid ids in the ParadeDB documents table to satisfy BM25 key_field requirements and adjust indexing/search to dump FlakeIds consistently. Also fix the ParadeDB backend unit test to avoid invalid pinning on struct fields.
This commit is contained in:
parent
efb75488d9
commit
dee7ac0415
2 changed files with 58 additions and 30 deletions
|
|
@ -67,37 +67,43 @@ defmodule Pleroma.Search.ParadeDB do
|
||||||
maybe_search_data = object_to_search_data(activity.object)
|
maybe_search_data = object_to_search_data(activity.object)
|
||||||
|
|
||||||
if activity.data["type"] == "Create" and maybe_search_data do
|
if activity.data["type"] == "Create" and maybe_search_data do
|
||||||
|
dumped_activity_id = dump_activity_id(activity.id)
|
||||||
actor_ap_id = activity.data["actor"]
|
actor_ap_id = activity.data["actor"]
|
||||||
published_at = DateTime.from_unix!(maybe_search_data.published)
|
published_at = DateTime.from_unix!(maybe_search_data.published)
|
||||||
|
|
||||||
sql =
|
if is_nil(dumped_activity_id) do
|
||||||
"""
|
Logger.error("ParadeDB add_to_index failed: invalid activity id #{inspect(activity.id)}")
|
||||||
INSERT INTO #{table()} (id, object_id, object_ap_id, actor_ap_id, content, published_at)
|
:ok
|
||||||
VALUES ($1, $2, $3, $4, $5, $6)
|
else
|
||||||
ON CONFLICT (id) DO UPDATE SET
|
sql =
|
||||||
object_id = EXCLUDED.object_id,
|
"""
|
||||||
object_ap_id = EXCLUDED.object_ap_id,
|
INSERT INTO #{table()} (id, object_id, object_ap_id, actor_ap_id, content, published_at)
|
||||||
actor_ap_id = EXCLUDED.actor_ap_id,
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
content = EXCLUDED.content,
|
ON CONFLICT (id) DO UPDATE SET
|
||||||
published_at = EXCLUDED.published_at
|
object_id = EXCLUDED.object_id,
|
||||||
"""
|
object_ap_id = EXCLUDED.object_ap_id,
|
||||||
|
actor_ap_id = EXCLUDED.actor_ap_id,
|
||||||
|
content = EXCLUDED.content,
|
||||||
|
published_at = EXCLUDED.published_at
|
||||||
|
"""
|
||||||
|
|
||||||
params = [
|
params = [
|
||||||
activity.id,
|
dumped_activity_id,
|
||||||
maybe_search_data.id,
|
maybe_search_data.id,
|
||||||
maybe_search_data.ap,
|
maybe_search_data.ap,
|
||||||
actor_ap_id,
|
actor_ap_id,
|
||||||
maybe_search_data.content,
|
maybe_search_data.content,
|
||||||
published_at
|
published_at
|
||||||
]
|
]
|
||||||
|
|
||||||
case client_impl().query(sql, params) do
|
case client_impl().query(sql, params) do
|
||||||
{:ok, _} ->
|
{:ok, _} ->
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
Logger.error("ParadeDB add_to_index failed: #{inspect(error)}")
|
Logger.error("ParadeDB add_to_index failed: #{inspect(error)}")
|
||||||
{:error, error}
|
{:error, error}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
:ok
|
:ok
|
||||||
|
|
@ -139,7 +145,10 @@ defmodule Pleroma.Search.ParadeDB do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp fetch_activities(ids, user, query, author) do
|
defp fetch_activities(ids, user, query, author) do
|
||||||
dumped_ids = Enum.map(ids, &FlakeId.from_string/1)
|
dumped_ids =
|
||||||
|
ids
|
||||||
|
|> Enum.map(&dump_activity_id/1)
|
||||||
|
|> Enum.reject(&is_nil/1)
|
||||||
|
|
||||||
from(a in Activity, where: a.id in ^dumped_ids)
|
from(a in Activity, where: a.id in ^dumped_ids)
|
||||||
|> Activity.with_preloaded_object()
|
|> Activity.with_preloaded_object()
|
||||||
|
|
@ -189,7 +198,7 @@ defmodule Pleroma.Search.ParadeDB do
|
||||||
defp create_table_sql(table) do
|
defp create_table_sql(table) do
|
||||||
"""
|
"""
|
||||||
CREATE TABLE IF NOT EXISTS #{table} (
|
CREATE TABLE IF NOT EXISTS #{table} (
|
||||||
id text PRIMARY KEY,
|
id uuid PRIMARY KEY,
|
||||||
object_id bigint NOT NULL,
|
object_id bigint NOT NULL,
|
||||||
object_ap_id text NOT NULL,
|
object_ap_id text NOT NULL,
|
||||||
actor_ap_id text,
|
actor_ap_id text,
|
||||||
|
|
@ -210,4 +219,15 @@ defmodule Pleroma.Search.ParadeDB do
|
||||||
WITH (key_field = 'id')
|
WITH (key_field = 'id')
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp dump_activity_id(<<_::binary-size(16)>> = uuid), do: uuid
|
||||||
|
|
||||||
|
defp dump_activity_id(id) when is_binary(id) do
|
||||||
|
case FlakeId.Ecto.CompatType.dump(id) do
|
||||||
|
{:ok, <<_::binary-size(16)>> = uuid} -> uuid
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp dump_activity_id(_), do: nil
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@ defmodule Pleroma.Search.ParadeDBTest do
|
||||||
|
|
||||||
[activity_id, object_id, object_ap_id, actor_ap_id, content, published_at] = params
|
[activity_id, object_id, object_ap_id, actor_ap_id, content, published_at] = params
|
||||||
|
|
||||||
assert activity_id == activity.id
|
{:ok, dumped_activity_id} = FlakeId.Ecto.CompatType.dump(activity.id)
|
||||||
|
|
||||||
|
assert activity_id == dumped_activity_id
|
||||||
assert is_integer(object_id)
|
assert is_integer(object_id)
|
||||||
assert is_binary(object_ap_id)
|
assert is_binary(object_ap_id)
|
||||||
assert actor_ap_id == activity.data["actor"]
|
assert actor_ap_id == activity.data["actor"]
|
||||||
|
|
@ -144,12 +146,18 @@ defmodule Pleroma.Search.ParadeDBTest do
|
||||||
{:ok, activity1} = CommonAPI.post(user, %{status: "first swamp", visibility: "public"})
|
{:ok, activity1} = CommonAPI.post(user, %{status: "first swamp", visibility: "public"})
|
||||||
{:ok, activity2} = CommonAPI.post(user, %{status: "second swamp", visibility: "public"})
|
{:ok, activity2} = CommonAPI.post(user, %{status: "second swamp", visibility: "public"})
|
||||||
|
|
||||||
|
activity1_id = activity1.id
|
||||||
|
activity2_id = activity2.id
|
||||||
|
|
||||||
|
{:ok, dumped_activity1_id} = FlakeId.Ecto.CompatType.dump(activity1_id)
|
||||||
|
{:ok, dumped_activity2_id} = FlakeId.Ecto.CompatType.dump(activity2_id)
|
||||||
|
|
||||||
ClientMock
|
ClientMock
|
||||||
|> expect(:query, fn sql, params ->
|
|> expect(:query, fn sql, params ->
|
||||||
assert sql =~ "SELECT id FROM pleroma_search_documents"
|
assert sql =~ "SELECT id FROM pleroma_search_documents"
|
||||||
assert ["swamp", _limit, _offset] = params
|
assert ["swamp", _limit, _offset] = params
|
||||||
|
|
||||||
{:ok, %{rows: [[activity2.id], [activity1.id]]}}
|
{:ok, %{rows: [[dumped_activity2_id], [dumped_activity1_id]]}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Config
|
Config
|
||||||
|
|
@ -161,7 +169,7 @@ defmodule Pleroma.Search.ParadeDBTest do
|
||||||
"pleroma_search_documents"
|
"pleroma_search_documents"
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert [%{id: ^activity2.id}, %{id: ^activity1.id}] =
|
assert [%{id: ^activity2_id}, %{id: ^activity1_id}] =
|
||||||
ParadeDB.search(nil, "swamp", limit: 40, offset: 0)
|
ParadeDB.search(nil, "swamp", limit: 40, offset: 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue