optimized people search
This commit is contained in:
parent
5e39368414
commit
f560321626
6 changed files with 53 additions and 26 deletions
|
|
@ -47,39 +47,25 @@ class Person < ActiveRecord::Base
|
||||||
def self.search_query_string(query)
|
def self.search_query_string(query)
|
||||||
if postgres?
|
if postgres?
|
||||||
where_clause = <<-SQL
|
where_clause = <<-SQL
|
||||||
profiles.first_name ILIKE ? OR
|
profiles.full_name ILIKE ? OR
|
||||||
profiles.last_name ILIKE ? OR
|
profiles.diaspora_handle ILIKE ?
|
||||||
people.diaspora_handle ILIKE ?
|
|
||||||
SQL
|
SQL
|
||||||
else
|
else
|
||||||
where_clause = <<-SQL
|
where_clause = <<-SQL
|
||||||
profiles.first_name LIKE ? OR
|
profiles.full_name LIKE ? OR
|
||||||
profiles.last_name LIKE ? OR
|
people.diaspora_handle LIKE ?
|
||||||
people.diaspora_handle LIKE ? OR
|
|
||||||
profiles.first_name LIKE ? OR
|
|
||||||
profiles.last_name LIKE ?
|
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
sql = ""
|
q_tokens = query.to_s.strip.gsub(/(\s|$|^)/) { "%#{$1}" }
|
||||||
tokens = []
|
[where_clause, [q_tokens, q_tokens]]
|
||||||
|
|
||||||
query_tokens = query.to_s.strip.split(" ")
|
|
||||||
query_tokens.each_with_index do |raw_token, i|
|
|
||||||
token = "#{raw_token}%"
|
|
||||||
up_token = "#{raw_token.titleize}%"
|
|
||||||
sql << " OR " unless i == 0
|
|
||||||
sql << where_clause
|
|
||||||
tokens.concat([token, token, token])
|
|
||||||
tokens.concat([up_token, up_token]) unless postgres?
|
|
||||||
end
|
|
||||||
[sql, tokens]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.search(query, user)
|
def self.search(query, user)
|
||||||
return [] if query.to_s.blank? || query.to_s.length < 3
|
return [] if query.to_s.blank? || query.to_s.length < 3
|
||||||
|
|
||||||
sql, tokens = self.search_query_string(query)
|
sql, tokens = self.search_query_string(query)
|
||||||
|
|
||||||
Person.searchable.where(sql, *tokens).joins(
|
Person.searchable.where(sql, *tokens).joins(
|
||||||
"LEFT OUTER JOIN contacts ON contacts.user_id = #{user.id} AND contacts.person_id = people.id"
|
"LEFT OUTER JOIN contacts ON contacts.user_id = #{user.id} AND contacts.person_id = people.id"
|
||||||
).includes(:profile
|
).includes(:profile
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class Profile < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
before_save do
|
before_save do
|
||||||
self.build_tags
|
self.build_tags
|
||||||
|
self.construct_full_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscribers(user)
|
def subscribers(user)
|
||||||
|
|
@ -120,6 +121,13 @@ class Profile < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Constructs a full name by joining #first_name and #last_name
|
||||||
|
# @returns [String] A full name
|
||||||
|
def construct_full_name
|
||||||
|
self.full_name = [self.first_name, self.last_name].join(' ').downcase
|
||||||
|
self.full_name
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def strip_names
|
def strip_names
|
||||||
self.first_name.strip! if self.first_name
|
self.first_name.strip! if self.first_name
|
||||||
|
|
|
||||||
22
db/migrate/20110729045734_add_full_name_to_profile.rb
Normal file
22
db/migrate/20110729045734_add_full_name_to_profile.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
class AddFullNameToProfile < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
add_column :profiles, :full_name, :string, :limit => 70
|
||||||
|
|
||||||
|
add_index :profiles, :full_name
|
||||||
|
add_index :profiles, [:full_name, :searchable]
|
||||||
|
remove_index :profiles, [:first_name, :last_name, :searchable]
|
||||||
|
remove_index :profiles, [:first_name, :searchable]
|
||||||
|
remove_index :profiles, [:last_name, :searchable]
|
||||||
|
|
||||||
|
execute("UPDATE profiles SET full_name=LOWER(CONCAT(first_name, ' ', last_name))")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
remove_index :profiles, :column => :full_name
|
||||||
|
remove_column :profiles, :full_name
|
||||||
|
|
||||||
|
add_index :profiles, [:first_name, :searchable]
|
||||||
|
add_index :profiles, [:last_name, :searchable]
|
||||||
|
add_index :profiles, [:first_name, :last_name, :searchable]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20110710102747) do
|
ActiveRecord::Schema.define(:version => 20110729045734) do
|
||||||
|
|
||||||
create_table "aspect_memberships", :force => true do |t|
|
create_table "aspect_memberships", :force => true do |t|
|
||||||
t.integer "aspect_id", :null => false
|
t.integer "aspect_id", :null => false
|
||||||
|
|
@ -295,11 +295,11 @@ ActiveRecord::Schema.define(:version => 20110710102747) do
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.string "location"
|
t.string "location"
|
||||||
|
t.string "full_name", :limit => 70
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "profiles", ["first_name", "last_name", "searchable"], :name => "index_profiles_on_first_name_and_last_name_and_searchable"
|
add_index "profiles", ["full_name", "searchable"], :name => "index_profiles_on_full_name_and_searchable"
|
||||||
add_index "profiles", ["first_name", "searchable"], :name => "index_profiles_on_first_name_and_searchable"
|
add_index "profiles", ["full_name"], :name => "index_profiles_on_full_name"
|
||||||
add_index "profiles", ["last_name", "searchable"], :name => "index_profiles_on_last_name_and_searchable"
|
|
||||||
add_index "profiles", ["person_id"], :name => "index_profiles_on_person_id"
|
add_index "profiles", ["person_id"], :name => "index_profiles_on_person_id"
|
||||||
|
|
||||||
create_table "service_users", :force => true do |t|
|
create_table "service_users", :force => true do |t|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ describe Person do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
describe '#diaspora_handle' do
|
describe '#diaspora_handle' do
|
||||||
context 'local people' do
|
context 'local people' do
|
||||||
it 'uses the pod config url to set the diaspora_handle' do
|
it 'uses the pod config url to set the diaspora_handle' do
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,18 @@ describe Profile do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#contruct_full_name' do
|
||||||
|
it 'generates a full name given first and last names' do
|
||||||
|
profile = Factory(:person).profile
|
||||||
|
profile.first_name = "casimiro"
|
||||||
|
profile.last_name = "grippi"
|
||||||
|
|
||||||
|
profile.full_name.should_not == "casimiro grippi"
|
||||||
|
profile.save
|
||||||
|
profile.full_name.should == "casimiro grippi"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "of last_name" do
|
describe "of last_name" do
|
||||||
it "strips leading and trailing whitespace" do
|
it "strips leading and trailing whitespace" do
|
||||||
profile = Factory.build(:profile, :last_name => " Ohba ")
|
profile = Factory.build(:profile, :last_name => " Ohba ")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue