|
|
|
@ -34,6 +34,31 @@ defmodule GcIndexRelay.Nostr.PublicationSearch do |
|
|
|
defp clamp_limit(_), do: 25 |
|
|
|
defp clamp_limit(_), do: 25 |
|
|
|
|
|
|
|
|
|
|
|
defp do_search(needles, limit) do |
|
|
|
defp do_search(needles, limit) do |
|
|
|
|
|
|
|
tag_match = metadata_tag_match(needles) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
events = |
|
|
|
|
|
|
|
from(e in Event, |
|
|
|
|
|
|
|
as: :event, |
|
|
|
|
|
|
|
where: e.kind == ^@publication_kind, |
|
|
|
|
|
|
|
where: |
|
|
|
|
|
|
|
exists( |
|
|
|
|
|
|
|
from(t in Tag, |
|
|
|
|
|
|
|
where: t.event_id == parent_as(:event).id, |
|
|
|
|
|
|
|
where: t.name in ^@search_tag_names, |
|
|
|
|
|
|
|
where: not is_nil(t.value), |
|
|
|
|
|
|
|
where: ^tag_match |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
order_by: [desc: e.created_at], |
|
|
|
|
|
|
|
limit: ^limit, |
|
|
|
|
|
|
|
preload: [:tags] |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|> Repo.all() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub_events_from_db(events) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defp metadata_tag_match(needles) do |
|
|
|
spaced_needles = Enum.map(needles, &spaced_form/1) |> Enum.uniq() |
|
|
|
spaced_needles = Enum.map(needles, &spaced_form/1) |> Enum.uniq() |
|
|
|
|
|
|
|
|
|
|
|
tag_match = |
|
|
|
tag_match = |
|
|
|
@ -48,38 +73,12 @@ defmodule GcIndexRelay.Nostr.PublicationSearch do |
|
|
|
) |
|
|
|
) |
|
|
|
end) |
|
|
|
end) |
|
|
|
|
|
|
|
|
|
|
|
# Also match when the stored value's spaced form equals any spaced needle. |
|
|
|
Enum.reduce(spaced_needles, tag_match, fn spaced, acc -> |
|
|
|
tag_match = |
|
|
|
dynamic( |
|
|
|
Enum.reduce(spaced_needles, tag_match, fn spaced, acc -> |
|
|
|
[t], |
|
|
|
dynamic( |
|
|
|
^acc or fragment("LOWER(TRIM(REPLACE(?, '-', ' '))) = ?", t.value, ^spaced) |
|
|
|
[t], |
|
|
|
|
|
|
|
^acc or fragment("LOWER(TRIM(REPLACE(?, '-', ' '))) = ?", t.value, ^spaced) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
event_ids = |
|
|
|
|
|
|
|
from(t in Tag, |
|
|
|
|
|
|
|
inner_join: e in Event, |
|
|
|
|
|
|
|
on: t.event_id == e.id, |
|
|
|
|
|
|
|
where: e.kind == ^@publication_kind, |
|
|
|
|
|
|
|
where: t.name in ^@search_tag_names, |
|
|
|
|
|
|
|
where: ^tag_match, |
|
|
|
|
|
|
|
distinct: e.id, |
|
|
|
|
|
|
|
order_by: [desc: e.created_at], |
|
|
|
|
|
|
|
limit: ^limit, |
|
|
|
|
|
|
|
select: e.id |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|> Repo.all() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
events = |
|
|
|
|
|
|
|
from(e in Event, |
|
|
|
|
|
|
|
where: e.id in ^event_ids, |
|
|
|
|
|
|
|
order_by: [desc: e.created_at], |
|
|
|
|
|
|
|
preload: [:tags] |
|
|
|
|
|
|
|
) |
|
|
|
) |
|
|
|
|> Repo.all() |
|
|
|
end) |
|
|
|
|
|
|
|
|
|
|
|
pub_events_from_db(events) |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
defp pub_events_from_db(events) do |
|
|
|
defp pub_events_from_db(events) do |
|
|
|
|