Improve hashtag search with multi word queries

This commit is contained in:
Mark Felder 2025-07-31 17:46:32 -07:00
commit 93c144e397
4 changed files with 92 additions and 6 deletions

View file

@ -38,6 +38,35 @@ defmodule Pleroma.HashtagTest do
assert results == []
end
test "searches hashtags by multiple words in query" do
# Create some hashtags
{:ok, _} = Hashtag.get_or_create_by_name("computer")
{:ok, _} = Hashtag.get_or_create_by_name("laptop")
{:ok, _} = Hashtag.get_or_create_by_name("desktop")
{:ok, _} = Hashtag.get_or_create_by_name("phone")
# Search for "new computer" - should return "computer"
results = Hashtag.search("new computer")
assert "computer" in results
refute "laptop" in results
refute "desktop" in results
refute "phone" in results
# Search for "computer laptop" - should return both
results = Hashtag.search("computer laptop")
assert "computer" in results
assert "laptop" in results
refute "desktop" in results
refute "phone" in results
# Search for "new phone" - should return "phone"
results = Hashtag.search("new phone")
assert "phone" in results
refute "computer" in results
refute "laptop" in results
refute "desktop" in results
end
test "supports pagination" do
{:ok, _} = Hashtag.get_or_create_by_name("alpha")
{:ok, _} = Hashtag.get_or_create_by_name("beta")
@ -50,5 +79,20 @@ defmodule Pleroma.HashtagTest do
results = Hashtag.search("a", limit: 2, offset: 1)
assert length(results) == 2
end
test "handles many search terms efficiently" do
# Create hashtags
{:ok, _} = Hashtag.get_or_create_by_name("computer")
{:ok, _} = Hashtag.get_or_create_by_name("laptop")
{:ok, _} = Hashtag.get_or_create_by_name("phone")
{:ok, _} = Hashtag.get_or_create_by_name("tablet")
# Search with many terms - should be efficient with PostgreSQL ANY operator
results = Hashtag.search("new fast computer laptop phone tablet device")
assert "computer" in results
assert "laptop" in results
assert "phone" in results
assert "tablet" in results
end
end
end

View file

@ -139,6 +139,37 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
assert results["hashtags"] == []
end
test "searches hashtags by multiple words in query", %{conn: conn} do
user = insert(:user)
{:ok, _activity1} = CommonAPI.post(user, %{status: "This is my new #computer"})
{:ok, _activity2} = CommonAPI.post(user, %{status: "Check out this #laptop"})
{:ok, _activity3} = CommonAPI.post(user, %{status: "My #desktop setup"})
{:ok, _activity4} = CommonAPI.post(user, %{status: "New #phone arrived"})
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "new computer"})}")
|> json_response_and_validate_schema(200)
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
assert "computer" in hashtag_names
refute "laptop" in hashtag_names
refute "desktop" in hashtag_names
refute "phone" in hashtag_names
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "computer laptop"})}")
|> json_response_and_validate_schema(200)
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
assert "computer" in hashtag_names
assert "laptop" in hashtag_names
refute "desktop" in hashtag_names
refute "phone" in hashtag_names
end
test "supports pagination of hashtags search results", %{conn: conn} do
user = insert(:user)