34465


Railsでカタカナの大文字小文字を無視した検索したい時に現状は

[code]

    str.tr('ァィゥェォヵヶッャュョヮ','アイウエオカケツヤユヨワ')
    
[/code]

などのようにして検索対象の文字列の小文字を大文字に変えたコピーのカラムを作り、検索で渡される文字列も同様に大文字に変換してから `ILIKE`
を使ってマッチさせています。

Postgresqlを使ったRails環境で何かもっと推奨されるシンプルな方法はありますか？


CC BY-SA 3.0
2017-05-01T23:13:02.550
34411
2017-05-17T04:36:48.870
3271
question
ruby-on-rails postgresql
カタカナの大文字小文字を無視した検索方法


DB ではありませんが、以前、正規表現を使って似たようなことをやったことがあります。

[code]

    table = {
      'ァ' => '[ァア]',
      'ア' => '[ァア]',
      'ィ' => '[ィイ]',
      'イ' => '[ィイ]',
      #...
    }
    
[/code]

のようなテーブルをあらかじめ作っておき、例えば 'キャット' を検索したい時には、  
このテーブルを使って 'キ[ャヤ][ッツ]ト' を作り出し、マッチさせました。

推奨はされないと思いますし、シンプルでもないと思いますが、参考として。


CC BY-SA 3.0
2017-05-04T02:37:30.873
34449
2017-05-04T02:37:30.873
5288
34411
answer


こういうのはデータベース側で「照合順序」に「カナの区別を行わない」を指定するだけのはず、だと思うわけです。と思って調査すると
[postgresql](/questions/tagged/postgresql "'postgresql' のタグが付いた質問を表示")
にはそういう照合順序がないらしい？マジっすか？

たとえばこんなことをしている記事を発見  
<http://blog.honjala.net/entry/2016/11/18/011752>

[ruby-on-rails](/questions/tagged/ruby-on-rails "'ruby-on-rails'
のタグが付いた質問を表示") でどう扱うと自然なのかはオイラではわからないので詳しい人にお任せ。


CC BY-SA 3.0
2017-05-04T11:59:06.337
34460
2017-05-04T11:59:06.337
8589
34411
answer


自分の知る限りでは、実際問題としては、ironsandさんが例示した今のやり方が一番シンプルだと思います。

必ずしもシンプルにはなりませんが、自然言語処理的なアプローチで行くと、例えば
[lucine](https://lucene.apache.org/core/) \+ [kuromoji](http://atilika.org/)
の組み合わせで、ライブラリをうまく使うと、文字の正規化の処理については機械的に処理させて、railsでは具体的なその手の処理を書くことを端折ることは可能だと思います。もしかすると[mecab](https://taku910.github.io/mecab/)でも代用できる部分があるかもしれません。  
（文字の正規化には、「、」や「。」などの文字を省いたり、大文字小文字を揃えたり、他にもなんパターンかが全文検索系のアルゴリズムでは使われています）  
この分野は私も学習中なので実コードで出すだけの手間と確証がとれませんでして、概要程度のことしか申せなくてすみません。あくまでもそんなアプローチもあるにはありそうだ、ということで参考程度にして下されば幸いです。


CC BY-SA 3.0
2017-05-05T06:28:02.033
34465
2017-05-05T06:28:02.033
9403
34411
answer


カタカナの大文字小文字程度であれば、カラムの値を`translate`関数で

[code]

    SELECT * FROM hoge WHERE translate(column, 'ァィゥェォヵヶッャュョヮ','アイウエオカケツヤユヨワ') ILIKE ?
    
[/code]

などと変換して比較する方法も考えられます。

検索時に変換コストが生じますが、検索用カラムをメンテナンスする手間はありません。変換コストは関数インデックスが適用できれば低減できます。


CC BY-SA 3.0
2017-05-17T04:36:48.870
34769
2017-05-17T04:36:48.870
5793
34411
answer