Programmer's Reference Guide
| インデックスの検索 |
クエリ言語
Java Lucene および Zend_Search_Lucene では、非常に強力なクエリ言語を使用できます。
これらの言語はほぼ同じものですが、微妙に異なる点もあります。 異なる点については以下で説明します。
Java Lucene のクエリ言語の文法についての完全な文書は » ここ にあります。
用語
クエリは、単語と演算子から成り立ちます。単語には三種類の形式があります。 単一の単語、フレーズ、そしてサブクエリです。
単一の単語とは、"test" や "hello" のようなひとつの単語です。
フレーズとは、ダブルクォートで囲まれた複数の単語のグループ、たとえば "hello dolly" です。
サブクエリとは、括弧で囲まれたクエリ、たとえば "(hello dolly)" です。
複数の単語を論理演算子で組み合わせることで、より複雑なクエリを作成できます (以下を参照ください)。
フィールド
Lucene は、フィールド指定したデータをサポートしています。 検索を行う際には、クエリを指定することもできますし、 デフォルトのフィールドを使用することもできます。 フィールド名はインデックス化されたデータに依存します。また、 デフォルトのフィールドは現在の設定によって決まります。
Java Lucene との最初の (そしてもっとも大きな) 違いは、デフォルトでは すべてのフィールド が検索の対象になるということです。
Zend_Search_Lucene クラスにはふたつの静的メソッドがあり、 この設定を操作することができます。
- $defaultSearchField = Zend_Search_Lucene::getDefaultSearchField();
- ...
- Zend_Search_Lucene::setDefaultSearchField('contents');
NULL 値は、すべてのフィールドを検索の対象とすることを意味します。 これがデフォルトの設定です。
特定のフィールドを検索するには、まずフィールド名をタイプし、その後にコロン ":" を続け、探したい単語を指定します。
例を見てみましょう。Lucene インデックスにはふたつのフィールド title および text があり、text がデフォルトのフィールドであるとします。 タイトルが "The Right Way" で本文に "don't go this way" が含まれるドキュメントを探したいなら、
- title:"The Right Way" AND text:go
あるいは
- title:"Do it right" AND go
とします。"text" はデフォルトのフィールドなので、フィールドの指定は必須ではなくなります。
注意: フィールドが有効なのは、その直後にある単語、 フレーズあるいはサブクエリだけであることに注意しましょう。つまり、クエリ
- title:Do it right
ワイルドカード
Lucene は、単一の文字あるいは複数の文字を表すワイルドカードをサポートしています これは、単語検索でのみ使用可能です (フレーズクエリでは使用できません)。
単一の文字を表すワイルドカードは "?" です。
複数の文字を表すワイルドカードは "*" です。
単一文字のワイルドカードは、 単語の中の "?" を別の一文字に置き換えたものにマッチする単語を探します。 たとえば、"text" あるいは "test" を探したい場合は
- te?t
複数文字のワイルドカードは、0 個以上の任意の数の文字に対応します。 たとえば test、tests あるいは tester を探したい場合は
- test*
"?" や "*" は単語のどの部分でも使え、 また両方を同時に使うこともできます。たとえば
- *wr?t*
ZF 1.7.7 以降、ワイルドカードパターンにはワイルドカード以外のプレフィックスが必要となりました。
デフォルトのプレフィックスの長さは 3 (Java Lucene と同じ) です。
つまり "*", "te?t", "*wr?t*" といった単語は例外を引き起こします[1]
Zend_Search_Lucene_Search_QueryParserExceptionZend_Search_Lucene_Exception。
これは、Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() および
Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength()
メソッドで変更することができます。
単語の修正子
Lucene は、クエリの単語を修飾して幅広い検索オプションを指定することをサポートしています。
"~" 修正子を使用すると、 フレーズに対する近接検索や個別の単語に対するあいまい検索が可能となります。
範囲検索
範囲検索は、フィールドの値の下限と上限を指定して その範囲に含まれるドキュメントを探すものです。 最大値と最小値そのものを含めることも含めないこともできます。 並べ替えは、辞書順で行われます。
- mod_date:[20020101 TO 20030101]
- title:{Aida TO Carmen}
両端の値を含めるには角括弧 []、含めない場合は波括弧 {} でクエリを指定します。
フィールドを指定しなかった場合は、Zend_Search_Lucene はすべてのフィールドに対して範囲検索を行います。
- {Aida TO Carmen}
あいまい検索
Zend_Search_Lucene は、Java Lucene と同様にあいまい検索をサポートします。 これは、レーベンシュタイン距離のアルゴリズムにもとづくものです。 あいまい検索を行うには、チルダ記号 "~" を単語の最後に指定します。 たとえば、"roam" と似たスペルの単語を探すには、次のようなあいまい検索を使用します。
- roam~
- roam~0.8
マッチする単語の制限
ワイルドカード検索や範囲検索、あいまい検索は、マッチする単語が多くなりすぎる可能性があります。 そんな場合は検索のパフォーマンスが大幅に低下してしまいます。
そこで、Zend_Search_Lucene はマッチする単語数の制限をクエリ (サブクエリ) 単位で設定します。
この制限を取得したり設定したりするには
Zend_Search_Lucene::getTermsPerQueryLimit()/Zend_Search_Lucene::setTermsPerQueryLimit($limit)
メソッドを使用します。
デフォルトのマッチ数の制限は、クエリ単位で 1024 です。
近接検索
Lucene は、複数の単語が指定した範囲内にあらわれる状態の検索をサポートしています。 近接検索を行うには、チルダ記号 "~" をフレーズの最後に指定します。 たとえば、"Zend" と "Framework" がお互い 10 ワードの範囲内にあらわれるドキュメントを検索するには
- "Zend Framework"~10
単語の強調
Java Lucene および Zend_Search_Lucene は、 見つかった単語にもとづいてドキュメントの関連度を提供します。 ある単語の関連性を高くするには、キャレット記号 "^" に強調度 (数値) をあわせたものを、検索する単語の最後につなげます。 強調度を高くするほど、その単語の関連性が高くなります。
この機能を使用すると、単語の強調度によってドキュメントの関連性を制御できるようになります。 たとえば
- PHP framework
- PHP^4 framework
- "PHP framework"^4 "Zend Framework"
論理演算子
論理演算子によって、複数の単語を組み合わせることができます。 Lucene では、論理演算子として AND、"+"、OR、NOT および "-" をサポートしています。Java Lucene では論理演算子をすべて大文字にする必要がありますが、 Zend_Search_Lucene ではその必要はありません。
論理クエリを作成するための方式は、大きく AND、OR および NOT の組と "+"、"-" の組に分けられます。Java Lucene とは異なり、Zend_Search_Lucene ではこれらの二つの組を混ぜて使うことはできません。
AND/OR/NOT 形式を使用する場合は、AND/OR 演算子がすべてのクエリ単語の間に存在する必要があります。 各単語の前には NOT 演算子をつけることができます。AND 演算子の優先順位は OR より高くなります。これは Java Lucene の挙動とは異なります。
AND
AND 演算子の意味は、"AND グループ" のすべての単語がドキュメントにマッチしなければならないということです。
"PHP framework" および "Zend Framework" を含むドキュメントを検索するには
- "PHP framework" AND "Zend Framework"
OR
OR 演算子は、クエリをいくつかのオプションに分割します。
"PHP framework" あるいは "Zend Framework" を含むドキュメントを検索するには
- "PHP framework" OR "Zend Framework"
NOT
NOT 演算子は、NOT の後に続く単語を含むドキュメントを除外します。 しかし "AND グループ" が NOT 演算子つきの単語しか含まない場合は、 インデックス化されたドキュメント全体ではなく空の結果を返します。
"PHP framework" を含むが "Zend Framework" は含まないドキュメントを検索するには
- "PHP framework" AND NOT "Zend Framework"
&&、|| および ! 演算子
&&、|| および ! は、それぞれ AND、OR および NOT 演算子の代わりに使用します。
+
"+" 演算子 (必須演算子) は、 "+" 記号の後の単語が必ずドキュメントにマッチしなければならないことを意味します。
"Zend" を必ず含み、"Framework" を含んでも含まなくてもかまわないドキュメントを検索するには
- +Zend Framework
-
"-" 演算子 (禁止演算子) は、 "-" 記号の後の単語を含むドキュメントを検索結果から除外します。
"PHP framework" は含むが "Zend Framework" は含まないドキュメントを検索するには
- "PHP framework" -"Zend Framework"
演算子なし
演算子を使用しなかった場合は、 その挙動は "デフォルトの boolean 演算子" として定義されます。
これは、デフォルトでは OR となります。
つまり、その単語は任意となるということです。 その単語はドキュメント中に存在するかもしれないし、しないかもしれません。 ただ、その単語を含むドキュメントのほうが高いスコアとなります。
"PHP framework" は必須で "Zend Framework" は含んでも含まなくてもかまわないドキュメントを検索するには
- +"PHP framework" "Zend Framework"
デフォルトの boolean 演算子を設定したり取得したりするには、それぞれ Zend_Search_Lucene_Search_QueryParser::setDefaultOperator($operator) および Zend_Search_Lucene_Search_QueryParser::getDefaultOperator() を使用します。
これらのメソッドで使用する定数は、 Zend_Search_Lucene_Search_QueryParser::B_AND および Zend_Search_Lucene_Search_QueryParser::B_OR です。
グループ化
Java Lucene および Zend_Search_Lucene では、 括弧を使用して条件をグループ化することによるサブクエリの作成をサポートしています。 これは、クエリのロジックを制御したい場合や異なるスタイルの論理クエリを共用したい場合などに便利です。
- +(framework OR library) +php
フィールドのグループ化
Lucene では、括弧を使用して複数の条件をひとつのフィールドに適用することができます。
タイトルに単語 "return" とフレーズ "pink panther" の両方を含むドキュメントを検索するには
- title:(+return +"pink panther")
特殊文字のエスケープ
Lucene は、クエリの文法に含まれる特殊文字のエスケープをサポートしています。 特殊文字に含まれるの文字は次のとおりです。
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \
+ および - が単一の単語の中に含まれる場合は、通常の文字として扱われます。
これらの文字をエスケープするには、その文字の前に \ をつけます。 たとえば、(1+1):2 を検索するには
- \(1\+1\)\:2
| インデックスの検索 |
