0

私のユーザーモデルには次のものがあります:

ユーザー (id、fname、lname)

ユーザーを名前で検索するクエリが必要です。私は使用していました:

@users = User.find( :all,
                      :select => 'users.*',
                      :conditions => ["fname || ' ' || lname LIKE ?", '%'+"James Bond"+'%']
                    )

James を検索するとユーザー (James Bond) が返されますが、「Bond」を検索しても何も返されません。このクエリを更新して、ユーザーを fname,lname または fname と lname のいずれかで返すにはどうすればよいですか?

ありがとう

4

1 に答える 1

1

RoR でどのように指定するのかはわかりませんが、PostgreSQL レベルではトライグラム検索を使用したいようです。PostgreSQL バージョン 9.1 以降を使用している場合は、これを「K Nearest Neighbor」(KNN) 検索と組み合わせて、K 個の最適な一致を直接返すことができます。これは一般に、名前の他の「あいまい」検索手法よりも桁違いに高速です。

トリグラム サポートをインストールするには、マシンに contrib モジュールがある場合は、次のように入力します。

CREATE EXTENSION pg_trgm;

NOT NULL両方の名前フィールドが(述語で答えが混乱するのを避けるため) であると仮定するとCOALESCE、インデックスは次のように作成できます。

CREATE INDEX users_name ON users USING gist
  ((fname || ' ' || lname) gist_trgm_ops);

数ミリ秒で何百万ものレコードからおおよその一致を見つけることができます。

SELECT *
  FROM users
  ORDER BY (fname || ' ' || lname) <-> 'James Bond'
  LIMIT 10;

<->演算子は「距離」演算子です。でORDER BY定義されたインデックスに対する句に it を使用しgist_trgm_ops を使用するLIMITと、インデックスから「最も一致する」順序で行が返されます。

于 2012-08-23T02:14:05.703 に答える