14.4. クエリの形式

14.4.1. 単一の単語のクエリ

ひとつの単語を使用した検索を行うためのものです。 以下の両方の方法が使用可能です。

文字列によるクエリ

    $hits = $index->find('word1');
        

あるいは

API で作成するクエリ

<?php

    $term  = new Zend_Search_Lucene_Index_Term('word1');
    $query = new Zend_Search_Lucene_Search_Query_Term($term);
    $hits  = $index->find($query);

?>

14.4.2. 複数の単語のクエリ

単語の組み合わせによる検索を行うためのものです。

各単語は、required (必須)prohibited (禁止)neither (どちらでもない) のいずれかを指定することができます。

  • required を指定した場合、 この単語を含まないドキュメントはクエリにマッチしません。

  • prohibited を指定した場合、 この単語を含むドキュメントはクエリにマッチしません。

  • neither を指定した場合、 この単語を含むドキュメントは除外されるわけでもなく、 この単語を含まなければマッチしないというわけでもありません。 ただし、クエリにマッチするためには、 この単語のうち最低ひとつを含まなければなりません。

つまり、必須単語のみのクエリに「どちらでもない (オプション)」 単語を追加しても、結果セットは変わりません。 ただ、オプションの単語にマッチした結果が結果セットの先頭に移動します。

以下の両方の方法が使用可能です。

文字列によるクエリ

<?php

$hits = $index->find('+word1 author:word2 -word3');

?>

  • 必須の単語には '+' を使用します。
  • 禁止する単語には '-' を使用します。
  • 検索するドキュメントフィールドを指定するには 'field:' を先頭につけます。これが省略された場合は 'contents' が使用されます。

あるいは

API で作成するクエリ

<?php

    $query = new Zend_Search_Lucene_Search_Query_MultiTerm();

    $query->addTerm(new Zend_Search_Lucene_Index_Term('word1'), true);
    $query->addTerm(new Zend_Search_Lucene_Index_Term('word2'), null);
    $query->addTerm(new Zend_Search_Lucene_Index_Term('word3'), false);

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

?>

$signs 配列に、単語の種別についての情報を含めます。

  • 必須の単語には true を使用します。
  • 禁止する単語には false を使用します。
  • 必須・禁止のどちらでもない場合は null を使用します。

14.4.3. フレーズクエリ

熟語による検索を行うためのものです。

フレーズクエリはとても柔軟性の高いもので、 完全な熟語だけでなく曖昧な熟語の検索も可能になります。 完全な熟語の場合、途中で隙間をあけたり複数の単語を同じ位置に指定したりもできます (これは、解析器によって別の目的で作成されます。 例えば、単語の重みを増すためにある単語を重複させたり、 類義語をひとつの位置にまとめたりします)。 フレーズクエリは、現在は API によってのみ行うことができます。

<?php
$query1 = new Zend_Search_Lucene_Search_Query_Phrase();

// 'word1' を 0 番目の位置に追加します。
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word1'));

// 'word2' を 1 番目の位置に追加します。
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word2'));

// 'word3' を 3 番目の位置に追加します。
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word3'), 3);

...

$query2 = new Zend_Search_Lucene_Search_Query_Phrase(
                array('word1', 'word2', 'word3'), array(0,1,3));

...

// 隙間をあけないクエリ
$query3 = new Zend_Search_Lucene_Search_Query_Phrase(
                array('word1', 'word2', 'word3'));

...

$query4 = new Zend_Search_Lucene_Search_Query_Phrase(
                array('word1', 'word2'), array(0,1), 'annotation');

?>

フレーズクエリを作成するには、コンストラクタで一気に構築してしまう方法と Zend_Search_Lucene_Search_Query_Phrase::addTerm() メソッドでひとつひとつ作成する方法に 2 通りがあります。

Zend_Search_Lucene_Search_Query_Phrase クラスのコンストラクタで、 オプションの 3 つの引数を指定することができます。

Zend_Search_Lucene_Search_Query_Phrase([array $terms[, array $offsets[, string $field]]]);

$terms は文字列の配列で、 フレーズを構成する単語が含まれます。指定しなかったり null を渡したりした場合は、空のクエリが作成されます。

$offsets は整数の配列で、 フレーズ内の単語の位置を指定します。指定しなかったり null を渡したりした場合は、単語の位置は array(0, 1, 2, 3, ...) であると解釈されます。

$field は文字列で、検索対象となるドキュメントのフィールドを指定します。 指定しなかったり null を渡したりした場合は、デフォルトのフィールドが対象となります。 このバージョンの Zend_Search_Lucene では、デフォルトのフィールドは 'contents' となります。しかし、次のバージョンではこれを "any field" に変更する予定です。

したがって、

$query = new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'framework'));

は 'zend framework' を検索します。

<$query = new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'download'), array(0, 2));

は 'zend ????? download' を検索し、'zend platform download' や 'zend studio download'、 'zend core download'、'zend framework download' などがマッチします

$query = new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'framework'), null, 'title');

は 'title' フィールドから 'zend framework' を検索します。

Zend_Search_Lucene_Search_Query_Phrase::addTerm() メソッドは 2 つの引数をとります。Zend_Search_Lucene_Index_Term オブジェクトが必須で、position はオプションです。

Zend_Search_Lucene_Search_Query_Phrase::addTerm(Zend_Search_Lucene_Index_Term $term[, integer $position]);

$term はフレーズ内の次の単語を指定します。 前の単語と同じフィールドを指していなければなりません。 そうでない場合は例外がスローされます。

$position は単語の位置を指定します。

したがって、

$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend'));
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework'));

は 'zend framework' を検索します。

$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend'), 0);
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework'), 2);

は 'zend ????? download' を検索し、'zend platform download' や 'zend studio download'、 'zend core download'、'zend framework download' などがマッチします

$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend', 'title'));
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework', 'title'));

は 'title' フィールドから 'zend framework' を検索します。

曖昧度は、フレーズの間に別の単語が何個まで入ることを許すのかを設定します。 ゼロの場合は、完全な熟語検索となります。大きな値を指定すると、 WITHIN 演算子や NEAR 演算子と同様な動作となります。

曖昧度とは、クエリの中で各単語の位置を何段階移動させられるかを表します。 例えば、2 つの単語の順番を入れ替えるには 2 段階の移動が必要です (最初の単語を、次の単語のもうひとつ先まで移動させます)。 そのため、語順を入れ替えることを許可したいのなら、曖昧度は少なくとも 2 以上にしなければなりません。

正確にマッチしているほうが、曖昧に (sloppy) マッチしているものより高スコアとなります。そのため、 検索結果は正確度の順に並べ替えられます。曖昧度のデフォルトはゼロで、 これは完全に一致するもののみを対象とします。

曖昧度は、クエリを作成した後で設定することができます。

<?php

// 隙間をあけないクエリ
$query = new Zend_Search_Lucene_Search_Query_Phrase(array('word1', 'word2'));

// 'word1 word2'、'word1 ... word2' を検索します
$query->setSlop(1);
$hits1 = $index->find($query);

// 'word1 word2'、'word1 ... word2'、
// 'word1 ... ... word2'、'word2 word1' を検索します
$query->setSlop(2);
$hits2 = $index->find($query);

?>