27.6. 文字セット

27.6.1. UTF-8 およびシングルバイト文字セットのサポート

Zend_Search_Lucene は、内部的には UTF-8 文字セットで動作します。 インデックスファイルには、unicode のデータが Java の "modified UTF-8 encoding" で保存されます。 Zend_Search_Lucene はこの文字セットを完全にサポートしていますが、 ひとつだけ例外があります。 [10]

実際の入力データのエンコーディングを指定するには Zend_Search_Lucene の API を使用します。 データは、自動的に UTF-8 エンコーディングに変換されます。

27.6.2. デフォルトのテキスト解析器

しかし、デフォルトのテキスト解析器 (クエリパーサの中でもこれが用いられます) は、 テキストやクエリのトークン化に ctype_alpha() を使用しています。

ctype_alpha() は UTF-8 と互換性がありません。 したがって、この解析器は テキストをインデックス化する前に 'ASCII//TRANSLIT' エンコーディングに変換します。 同じ処理がクエリのパース時にも行われますが、これは透過的に行われます。 [11]

27.6.3. UTF-8 互換のテキスト解析器

Zend_Search_Lucene には、機能限定版の UTF-8 解析器も含まれています。 これを有効にするには、以下のようなコードを使用します。

<?php
Zend_Search_Lucene_Analysis_Analyzer::setDefault(
    new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());

これは、データを UTF-8 モードでトークン化してインデックスを作成し、 UTF-8 互換の文字で何の問題もなく動作します。

制限事項は次のふたつです。

  • 非 ascii 文字を、すべて文字として扱う (常にそうだというわけではありません)

  • 大文字小文字を区別する

これらの制限があるためにこの解析器はデフォルトにはなっていません。 しかし、これが便利に使えるかたもいることでしょう。

大文字小文字を区別しないようにさせるには、 strtolower() による変換を使用します。

<?php
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');

...

Zend_Search_Lucene_Analysis_Analyzer::setDefault(
    new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());

...

$doc = new Zend_Search_Lucene_Document();

$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', strtolower($contents)));

// 検索用の Title フィールド (インデックス化しますが保存しません)
$doc->addField(Zend_Search_Lucene_Field::UnStored('title', strtolower($title)));

// 取得用の Title フィールド (インデックス化せず、保存します)
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('_title', $title));

同様の変換を、クエリ文字列でも行う必要があります。

<?php
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');

...

Zend_Search_Lucene_Analysis_Analyzer::setDefault(
    new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());

...

$hits = $index->find(strtolower($query));



[10] Zend_Search_Lucene では Basic Multilingual Plane (BMP) 文字 (0x0000 から 0xFFFF まで) のみをサポートしており、 "supplementary characters" (コードポイントが 0xFFFF より大きい文字) はサポートしていません。

Java 2 では、これらを文字 (16 ビット) のペアで表します。最初の文字が上位サロゲート (0xD800-0xDBFF)、 2 番目の文字が下位サロゲート (0xDC00-0xDFFF) となります。 その後、これらが 6 バイトの UTF-8 文字にエンコードされます。 標準的な UTF-8 では、supplementary characters を 4 バイトで表します。

[11] 'ASCII//TRANSLIT' への変換は、現在のロケールおよび OS に依存します。