0

これは、できれば宝石を使わずに達成したいことです。ビューの 1 つに検索機能があり、ユーザーが 1 つのフィールドに姓名を入力できるようにし、クラス メソッドで姓名の両方を検索してリストを生成できるようにしたいと考えています。現在、両方のフィールドで全文検索を行う次の醜いコードがあります。私を憐れんでください:)私はSQLとPostgreSQLが初めてです。基本的なクエリしか実行していません。

  def self.text_search(query)
    if query.present?
      q1, q2, q3, q4 = query.split(' ')
      case
      when q4 != nil
        where('first_name @@ :q1 OR first_name @@ :q2 OR first_name @@ :q3 OR first_name @@ :q4 OR last_name @@ :q1 OR last_name @@ :q2 OR last_name @@ :q3 OR last_name @@ :q4', q1: q1, q2: q2, q3: q3, q4: q4)
      when q3 != nil
        where('first_name @@ :q1 OR first_name @@ :q2 OR first_name @@ :q3 OR last_name @@ :q1 OR last_name @@ :q2 OR last_name @@ :q3', q1: q1, q2: q2, q3: q3)
      when q2 != nil
        where('first_name @@ :q1 OR first_name @@ :q2 OR last_name @@ :q1 OR last_name @@ :q2', q1: q1, q2: q2)
      else
        where('first_name @@ :q1 OR last_name @@ :q1', q1: q1)
      end
    else
      scoped
    end
  end

このコードは、両方のフィールドで単語全体を検索し、一致するすべてのレコードを生成する場合に機能します。しかし、私がやりたいことは、検索ボックスに入力された値から始まる列を検索できるようにすることです。たとえば、誰かが「パット」と入力すると、クエリはパット、パトリック、パトリス、パトリシアなどを選択します。必要なすべての値をリストできる場所に含めたコードでさえ、より良い方法で書くことができると確信しています。 first_name と last_name を確認してください (または、少なくともあることを願っています)。

私は今日、これに関して多くのウェブ検索を行ってきました。これのさまざまな側面に関する多くの情報を見つけました。変数を使用して正規表現を作成する方法を見ました。これは私には明らかでした。私の問題は、その情報を where 句に渡す方法を考え出すことでした。たとえば、4 つのフィールドすべてに対して次のコードを試しました。

qr1 = /^#{q1}/

次に、4 つの値すべてについて first_name と last_name の両方をチェックする同様の where 句を実行しました。私のクエリは行を返しませんでした。

where ('first_name ~ :qr1', qr1: qr1)

また、部分文字列を配列と比較してチェックする方法についても説明しました。その解決策で私が目にする問題は、それで成功する前に、入力された値がどれくらいの長さであるかを知る必要があるということです. 例を含むスタック オーバーフローの投稿を次に示します。

範囲内の最初の文字を選択 ( PostgreSQL )

to_tsvector と plainto_tsquery について説明している RailsCasts #343 (Pro) も見ましたが、率直に言って、道に迷ってしまいました。たぶんこれが私の答えですが、確かに助けが必要です。私には泥のように明らかです。

4

1 に答える 1

0
def self.text_search(query)
  if query.present?
    arr = query.split(' ').map { |q| "%#{q}" }

    where('first_name ~~* ANY(ARRAY[:arr]) OR last_name ~~* ANY(ARRAY[:arr])', arr: arr)
  else
    scoped
  end
end
于 2012-12-28T18:40:17.027 に答える