forked from forem/forem
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Search 2.0] Add Search::Postgres::Username behind a feature flag (fo…
…rem#12975) * Add PostgreSQL FTS for usernames * Change profile_image_90 logic * Make search_users private * Add tsvector index on usernames * Limit the number of search results * Update index name
- Loading branch information
1 parent
51b3a90
commit 1e4d4db
Showing
9 changed files
with
175 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module Search | ||
module Postgres | ||
class Username | ||
MAX_RESULTS = 6 | ||
|
||
ATTRIBUTES = %i[ | ||
id | ||
name | ||
profile_image | ||
username | ||
].freeze | ||
|
||
def self.search_documents(term) | ||
users = search_users(term) | ||
|
||
users.map do |user| | ||
user.as_json(only: %i[id name username]) | ||
.merge("profile_image_90" => user.profile_image_90) | ||
end | ||
end | ||
|
||
def self.search_users(term) | ||
::User | ||
.search_by_username(term) | ||
.limit(MAX_RESULTS) | ||
.select(*ATTRIBUTES) | ||
end | ||
|
||
private_class_method :search_users | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
db/migrate/20210312191925_add_username_tsvector_index_to_users.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
class AddUsernameTsvectorIndexToUsers < ActiveRecord::Migration[6.0] | ||
disable_ddl_transaction! | ||
|
||
INDEX = "to_tsvector('simple'::regconfig, COALESCE((username)::text, ''::text))" | ||
private_constant :INDEX | ||
|
||
def up | ||
return if index_exists?(:users, INDEX, name: "index_users_on_username_as_tsvector") | ||
|
||
add_index :users, | ||
INDEX, | ||
using: :gin, | ||
algorithm: :concurrently, | ||
name: "index_users_on_username_as_tsvector" | ||
end | ||
|
||
def down | ||
return unless index_exists?(:users, INDEX, name: "index_users_on_username_as_tsvector") | ||
|
||
remove_index :users, | ||
name: "index_users_on_username_as_tsvector", | ||
algorithm: :concurrently | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe Search::Postgres::Username, type: :service do | ||
it "defines necessary constants" do | ||
expect(described_class::ATTRIBUTES).not_to be_nil | ||
expect(described_class::MAX_RESULTS).not_to be_nil | ||
end | ||
|
||
describe "::search_documents" do | ||
it "returns data in the expected format" do | ||
user = create(:user) | ||
|
||
result = described_class.search_documents(user.username) | ||
|
||
expect(result.first.keys).to match_array( | ||
%w[id name profile_image_90 username], | ||
) | ||
end | ||
|
||
it "finds a user by their username" do | ||
user = create(:user) | ||
|
||
expect(described_class.search_documents(user.username)).to be_present | ||
end | ||
|
||
it "finds a user by a partial username" do | ||
user = create(:user) | ||
|
||
expect(described_class.search_documents(user.username.first(1))).to be_present | ||
end | ||
|
||
it "finds multiple users whose names have common parts", :aggregate_failures do | ||
alex = create(:user, username: "alex") | ||
alexsmith = create(:user, username: "alexsmith") | ||
rhymes = create(:user, username: "rhymes") | ||
|
||
result = described_class.search_documents("ale") | ||
usernames = result.map { |r| r["username"] } | ||
|
||
expect(usernames).to include(alex.username) | ||
expect(usernames).to include(alexsmith.username) | ||
expect(usernames).not_to include(rhymes.username) | ||
end | ||
|
||
it "limits the number of results to the value of MAX_RESULTS" do | ||
max_results = 1 | ||
stub_const("#{described_class}::MAX_RESULTS", max_results) | ||
|
||
alex = create(:user, username: "alex") | ||
alexsmith = create(:user, username: "alexsmith") | ||
|
||
results = described_class.search_documents("alex") | ||
|
||
expect(results.size).to eq(max_results) | ||
expect([alex.username, alexsmith.username]).to include(results.first["username"]) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters