2

PeopleテーブルにマップするPersonモデルを持つRubyonRailsアプリケーションがあります。このテーブルには、次のようにfirst_name、middle_name、およびlast_nameが含まれています。

John Q. Doe
John H. Doe
Jane M. Doe
Jim R. Doe, Jr.
Jack Timothy Doe

ここで、入力が特定の名前の派生語の省略形である場合に、テーブルに対して検索を実行する必要があります。略語は次の形式です。

  • 名の最初のイニシャルとそれに続くスペース
  • ミドルネームの最初のイニシャルとそれに続くスペース(ミドルネームがある場合)
  • フルラストネーム

例えば:

find_by_abbreviated_name("J Q Doe") => would find the John Q. Doe record
find_by_abbreviated_name("J T Doe") => would find the Jack Timothy Doe record
find_by_abbreviated_name("J R Doe, Jr.") => Jim R Doe, Jr.

Rubyには、ファーストネームとミドルネームの最初の文字をフルラストネームと組み合わせて使用​​して検索を行うための巧妙な方法がありますか。これを行う方法を考え出すことができるので、Personテーブルに別のフィールドを追加する必要はありません。

4

3 に答える 3

2

したがって、処理しなければならない問題は、入力要素を保証できない限り、入力の形式が異なることだと思います。真ん中がオプションで、最後に複数のトークンが含まれている可能性がある場合、単一の文字列として渡された場合に確実に解析できないものがあるという課題があります。

John Doe Jr
John Doe, Jr.
John Quentin Doe
John Doe Worthington-Smythe

(多くの名前には複数の部分があるなど)

したがって、個別の入力フィールドを提供するか、ユーザーにあいまいなケースを確認するか、いくつかのルールまたは一般的なケースに基づいていくつかの代替案を試すことで、これを処理できます。それでは、解析部分を待って、適切にフォーマットされた個別の入力があると仮定しましょう(たとえば、大文字の単一文字)。

def find_by_abbreviated_name(fist_init, middle_init, last_name)
  if middle_init.blank?
    People.where("first LIKE ? AND middle LIKE ? and LAST like ?", "#{first_init}%", "#{middle_init}%", "#{last_name}%")
  else
    People.where("first LIKE ? AND LAST LIKE ?", "#{first_init}%", "#{last_name}%")
  end
end

これにより、部分一致であるLIKE演算子を使用するSQLが生成されます。これは、ファイル名の一致や正規表現%と同様のSQLワイルドカード文字です。*.*

申し訳ありませんが、最初の3回の試行でエラーが発生しました。私は今、ワイルドカードをもっとうまくやる方法があるかどうかをチェックしています...

于 2012-11-19T01:09:31.340 に答える
1

洗練されたRubyの方法はありません。クエリを作成するだけです。このようなものが機能するはずです:

def self.find_by_abbreviated_name(name)
  if name[3].blank? && name.size >= 5 # Check if there's a middle initial
    where("first_name like ? and middle_name like ? and last_name = ?", "#{name[0]}%", "#{name[2]}%", name[4..-1])
  else # No middle initial
    where("first_name like ? and last_name = ?", "#{name[0]}%", name[2..-1])
  end
end

説明:

文字列という名前の「トリック」は、文字列の形式が常に同じである場合にのみ機能します。name[0]文字列の最初の文字をname[2]与え、3番目の文字を与えname[4..-1]、5番目の文字を文字列の最後に返します。

where条項自体はかなり簡単だと思います。最初の文字に基づいてレコードを検索するには、次を使用できます。.where('field_name like ?', "#{query}%")ここで、疑問符は実際に置換値のプレースホルダーです。

編集:

ミドルネームのイニシャルが省略されている場合の回答を更新しました。

于 2012-11-19T00:57:51.950 に答える
1

この問題は、文字列ランキングアルゴリズムを使用するための理想的な候補です。

Jquery/Prototypeを使用したQuicksilverアルゴリズムのこの実装を見てください。

基本的に、他の人がすでに述べたように、データが入力される形式を常に説明できるとは限らないため、これを行うのは面倒です。

アクティブな宝石やルビーのポートがあるとは思いませんが、それはかなり簡単です。

これをRailsアプリに実装すると、

  1. すべての人のIDと連結された名前を取得する
  2. その配列でアルゴリズムを実行する
  3. ソートされた配列からのIDに基づいて上位1/3/n行をフェッチします。

私は個人的にクエリを「構築」することをあまり頻繁に避けています。ARは私にとってORMとして十分に強力ではありません。しかし、そのルートに行く場合は、必ずARELが必須であるSqueelgemの失敗を確認する必要があります。

于 2012-11-19T07:18:41.140 に答える