これが私がすることです:
まず、検索用のメール アドレスやユーザー名フィールドなどのデータは、データベース内で小文字に正規化する必要があります。これにより、コーディングが大幅に簡素化されます。
ユーザーの姓名を表示する場合など、元の大文字と小文字を区別する必要がある場合は、それらを別個の姓名フィールドとして保持し、検索用に既に結合およびハッシュされている別のフィールドを作成し、そのフィールドを見ると、コード内の同じハッシュ。それがインデックス化されている場合、検索を使用する場合と比較して、like
検索が非常に高速になります。
where
SQL パーシャルを生成してクエリに挿入するのではなく、純粋な Sequel を使用してプログラムで生成するコードを次に示します。Sequel は SQLite の構文を認識しており、動作する where 句を自動的に作成することに注意してください。PostgreSQL、MySQL、Oracle、MSSQL、Sybase、または Sequel がサポートするその他の DBM に接続している場合も同様です。コードを機能させるためだけにコードを微調整する必要はありません。使用するドライバーと DB 資格情報を Sequel に伝える DSN を調整するだけです。
テスト DB の構築:
require 'sequel'
DB = Sequel.sqlite
DB.create_table :items do
primary_key :id
String :first_name
String :last_name
String :email
String :attr1, :default => 'attr'
String :attr2, :default => 'attr'
end
items = DB[:items]
%w[Jane Jim John Junior].each do |fn|
items.insert(:first_name => fn, :last_name => 'Doe', :email => fn.downcase + 'doe@email.com')
end
puts items.all
さあ、いくぞ...:
user_name = '%' + 'John Doe'.downcase + '%'
query = DB[:items].where(
Sequel.ilike(
Sequel.join([:first_name, :last_name], ' '),
user_name
)
)
columns = [:email, :attr1, :attr2]
columns.each do |col|
query = query.or(
Sequel.ilike(
col,
user_name.delete(' ')
)
)
end
puts query.sql
puts query.first
コードを実行すると、テーブルの内容が出力されます。
{:id=>1, :first_name=>"Jane", :last_name=>"Doe", :email=>"janedoe@email.com", :attr1=>"attr", :attr2=>"attr"}
{:id=>2, :first_name=>"Jim", :last_name=>"Doe", :email=>"jimdoe@email.com", :attr1=>"attr", :attr2=>"attr"}
{:id=>3, :first_name=>"John", :last_name=>"Doe", :email=>"johndoe@email.com", :attr1=>"attr", :attr2=>"attr"}
{:id=>4, :first_name=>"Junior", :last_name=>"Doe", :email=>"juniordoe@email.com", :attr1=>"attr", :attr2=>"attr"}
DB を照会するために生成された SQL:
SELECT * FROM `items` WHERE ((UPPER((`first_name` || ' ' || `last_name`)) LIKE UPPER('%john doe%') ESCAPE '\') OR (UPPER(`email`) LIKE UPPER('%johndoe%') ESCAPE '\') OR (UPPER(`attr1`) LIKE UPPER('%johndoe%') ESCAPE '\') OR (UPPER(`attr2`) LIKE UPPER('%johndoe%') ESCAPE '\'))
読みやすくするための書式設定:
SELECT * FROM `items`
WHERE (
(UPPER((`first_name` || ' ' || `last_name`)) LIKE UPPER('%john doe%') ESCAPE '\') OR
(UPPER(`email`) LIKE UPPER('%johndoe%') ESCAPE '\') OR
(UPPER(`attr1`) LIKE UPPER('%johndoe%') ESCAPE '\') OR
(UPPER(`attr2`) LIKE UPPER('%johndoe%') ESCAPE '\')
)
そして、クエリの後の結果の行:
{:id=>3, :first_name=>"John", :last_name=>"Doe", :email=>"johndoe@email.com", :attr1=>"attr", :attr2=>"attr"}
これは最も DRY なコードではありませんが、例としては要点を捉えています。