diff options
| -rw-r--r-- | lib/mix/tasks/sample_psql.eex | 1 | ||||
| -rw-r--r-- | lib/pleroma/user.ex | 21 | ||||
| -rw-r--r-- | priv/repo/migrations/20180516144508_add_trigram_extension.exs | 15 | ||||
| -rw-r--r-- | priv/repo/migrations/20180516154905_create_user_trigram_index.exs | 7 | ||||
| -rw-r--r-- | test/web/mastodon_api/mastodon_api_controller_test.exs | 23 | 
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"] == [] | 
