summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2018-05-16 17:55:20 +0200
committerlain <lain@soykaf.club>2018-05-16 17:55:20 +0200
commit1d4bbec6b3239bb83b500a6a90e6686cb682cfac (patch)
tree784685762399e4e2d2e630a2f20ece05b91b6809
parent2e9aa16b862fac043a5c1a538fc6eacdaa7ec56f (diff)
downloadpleroma-1d4bbec6b3239bb83b500a6a90e6686cb682cfac.tar.gz
pleroma-1d4bbec6b3239bb83b500a6a90e6686cb682cfac.zip
Fix User search.
Now uses a trigram based search. This is a lot faster and gives better results. Closes #185.
-rw-r--r--lib/mix/tasks/sample_psql.eex1
-rw-r--r--lib/pleroma/user.ex21
-rw-r--r--priv/repo/migrations/20180516144508_add_trigram_extension.exs15
-rw-r--r--priv/repo/migrations/20180516154905_create_user_trigram_index.exs7
-rw-r--r--test/web/mastodon_api/mastodon_api_controller_test.exs23
5 files changed, 54 insertions, 13 deletions
diff --git a/lib/mix/tasks/sample_psql.eex b/lib/mix/tasks/sample_psql.eex
index 18e322efc..bc22f166c 100644
--- a/lib/mix/tasks/sample_psql.eex
+++ b/lib/mix/tasks/sample_psql.eex
@@ -6,3 +6,4 @@ ALTER DATABASE pleroma_dev OWNER TO pleroma;
\c pleroma_dev;
--Extensions made by ecto.migrate that need superuser access
CREATE EXTENSION IF NOT EXISTS citext;
+CREATE EXTENSION IF NOT EXISTS pg_trgm;
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 207674999..399a66787 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -21,6 +21,7 @@ defmodule Pleroma.User do
field(:local, :boolean, default: true)
field(:info, :map, default: %{})
field(:follower_address, :string)
+ field(:search_distance, :float, virtual: true)
has_many(:notifications, Notification)
timestamps()
@@ -399,19 +400,23 @@ defmodule Pleroma.User do
User.get_or_fetch_by_nickname(query)
end
- q =
+ inner =
from(
u in User,
- where:
- fragment(
- "(to_tsvector('english', ?) || to_tsvector('english', ?)) @@ plainto_tsquery('english', ?)",
+ select_merge: %{
+ search_distance: fragment(
+ "? <-> (? || ?)",
+ ^query,
u.nickname,
- u.name,
- ^query
- ),
- limit: 20
+ u.name
+ )}
)
+ q = from(s in subquery(inner),
+ order_by: s.search_distance,
+ limit: 20
+ )
+
Repo.all(q)
end
diff --git a/priv/repo/migrations/20180516144508_add_trigram_extension.exs b/priv/repo/migrations/20180516144508_add_trigram_extension.exs
new file mode 100644
index 000000000..f2f0fca86
--- /dev/null
+++ b/priv/repo/migrations/20180516144508_add_trigram_extension.exs
@@ -0,0 +1,15 @@
+defmodule Pleroma.Repo.Migrations.AddTrigramExtension do
+ use Ecto.Migration
+ require Logger
+
+ def up do
+ Logger.warn("ATTENTION ATTENTION ATTENTION\n")
+ Logger.warn("This will try to create the pg_trgm extension on your database. If your database user does NOT have the necessary rights, you will have to do it manually and re-run the migrations.\nYou can probably do this by running the following:\n")
+ Logger.warn("sudo -u postgres psql pleroma_dev -c \"create extension if not exists pg_trgm\"\n")
+ execute("create extension if not exists pg_trgm")
+ end
+
+ def down do
+ execute("drop extension if exists pg_trgm")
+ end
+end
diff --git a/priv/repo/migrations/20180516154905_create_user_trigram_index.exs b/priv/repo/migrations/20180516154905_create_user_trigram_index.exs
new file mode 100644
index 000000000..abfa4b3cc
--- /dev/null
+++ b/priv/repo/migrations/20180516154905_create_user_trigram_index.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.CreateUserTrigramIndex do
+ use Ecto.Migration
+
+ def change do
+ create index(:users, ["(nickname || name) gist_trgm_ops"], name: :users_trigram_index, using: :gist)
+ end
+end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index 882c92682..8d79c96b1 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -609,16 +609,29 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
test "account search", %{conn: conn} do
user = insert(:user)
- _user_two = insert(:user, %{nickname: "shp@shitposter.club"})
+ user_two = insert(:user, %{nickname: "shp@shitposter.club"})
user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
- conn =
+ results =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/search", %{"q" => "shp"})
+ |> json_response(200)
+
+ result_ids = for result <- results, do: result["acct"]
+
+ assert user_two.nickname in result_ids
+ assert user_three.nickname in result_ids
+
+ results =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/search", %{"q" => "2hu"})
+ |> json_response(200)
- assert [account] = json_response(conn, 200)
- assert account["id"] == to_string(user_three.id)
+ result_ids = for result <- results, do: result["acct"]
+
+ assert user_three.nickname in result_ids
end
test "search", %{conn: conn} do
@@ -642,7 +655,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert results = json_response(conn, 200)
- [account] = results["accounts"]
+ [account | _] = results["accounts"]
assert account["id"] == to_string(user_three.id)
assert results["hashtags"] == []