私は特定の文章を索引付けしなければならないアプリケーションに取り組んでいます。現在、JavaとPostgreSQLを使用しています。文章は、フランス語やスペイン語などアクセント記号やその他の非ASCII記号を使用した複数の言語で表示されます。インデックス作成のために文字列をASCII 7文字に減らすには?
各単語について、ユーザーがアクセント(音訳)に敏感でない検索を実行できるように、インデックス可能な同等物を作成したいとします。たとえば、ユーザーが「nacion」を検索する場合、アプリケーションによって保存された元の単語が「Naci ó n」であっても、ユーザーは「nacion」を検索する必要があります。
これにはどのような戦略が最適でしょうか?私は必ずしもPostgreSQLだけに限定されているわけではなく、内部の索引付けされた値も元の単語と似ている必要はありません。理想的には、Unicode文字列を大文字と小文字の区別をしないASCII文字列に変換する汎用的なソリューションでなければなりません。
これまでのところ私は、索引付けされた値を保存する前にいくつかの文字をASCII相当物に置き換え、クエリ文字列で同じことをする次のようなカスタム関数を使用しています。
public String toIndexableASCII (String sStrIn) {
if (sStrIn==null) return null;
int iLen = sStrIn.length();
if (iLen==0) return sStrIn;
StringBuilder sStrBuff = new StringBuilder(iLen);
String sStr = sStrIn.toUpperCase();
for (int c=0; c<iLen; c++) {
switch (sStr.charAt(c)) {
case 'Á':
case 'À':
case 'Ä':
case 'Â':
case 'Å':
case 'Ã':
sStrBuff.append('A');
break;
case 'É':
case 'È':
case 'Ë':
case 'Ê':
sStrBuff.append('E');
break;
case 'Í':
case 'Ì':
case 'Ï':
case 'Î':
sStrBuff.append('I');
break;
case 'Ó':
case 'Ò':
case 'Ö':
case 'Ô':
case 'Ø':
sStrBuff.append('O');
break;
case 'Ú':
case 'Ù':
case 'Ü':
case 'Û':
sStrBuff.append('U');
break;
case 'Æ':
sStrBuff.append('E');
break;
case 'Ñ':
sStrBuff.append('N');
break;
case 'Ç':
sStrBuff.append('C');
break;
case 'ß':
sStrBuff.append('B');
break;
case (char)255:
sStrBuff.append('_');
break;
default:
sStrBuff.append(sStr.charAt(c));
}
}
return sStrBuff.toString();
}
バイトをASCII 7として解釈すると、達成したい "情報の損失"はありません。私は "coraçón"を "coracon"と同じにして、検索時にユーザーがアクセントを置くかどうかを問わないようにします。 Googleのようなスペルや近接チェッカーは必要ありません。しかし、私は "é" == "e"が必要です。 –
あなたが求めているマッピングは "音訳"と呼ばれています。 –
ありがとうございます。私は音訳を追加するために質問を編集し、Googleにいくつかの良いマッチを手伝った。 –