12.3. Het doorzoeken van een index

12.3.1. Opbouwen van Queries

Er zijn twee manieren om door een index te zoeken. De eerste methode gebruikt de Query Parser om een query op te bouwen van een string. De tweede bied de mogelijkheid je eigen queries te maken via de Zend_Search_Lucene API.

Alvorens te kiezen voor de aangeboden Query Parser, hou het volgende in gedachte:

  1. Wanneer je query string door je applicatie wordt opgebouwd dan moet je serieus overwegen om je queries op te bouwen met de query API. Met andere woorden: De query parser is bedoeld voor door mensen ingevoerde tekst, niet voor applicatie-gerelateerde tekst.
  2. Untokenized velden worden het best direct aan queries toegevoegd, en niet via de query parser. Wanneerde waarde van een veld via een applicatie wordt gegenereerd, dan dienen de query clases ook op die manier tot stand te komen voor dit veld. De query parser gebruikt een analyzer om door mensen ingegeven strings to converteren van tekst naar termen. Waardes gegenereerd door een programma, zoals data, trefwoorden, etc. dienen consistent door het programma gegenereerd te worden.
  3. In een query formulier dienen velden die over het algemeen tekst bevatten de query parser te gebruiken. Alle andere velden, zoals datum ranges, trefwoorden etc. kunnen het beste direct via de query API worden toegevoegd. Een veld met een gelimiteerde set van waarden, die kan worden geselecteerd via een pull-down menu, horen niet via een query string toegevoegd en geparsed worden, maar via een TermQuery clausule.

Beide manieren gebruiken dezelfde API methode om door de index te zoeken:

<?php

require_once('Zend/Search/Lucene.php');

$index = new Zend_Search_Lucene('/data/my_index');

$index->find($query);

?>

De Zend_Search_Lucene::find() methode herkent automatisch het invoer type en gebruikt de query parser om het juiste Zend_Search_Lucene_Search_Query object van een string te maken.

Het is belangrijk om te zien dat find() case sensitive is. Standaard normaliseert LuceneIndexCreation.jar alle documenten naar kleine letters. Dit kan uitgezet worden met een command line switch (type LuceneIndexCreation.jar zonder argumenten voor hulp). De case van de tekst die aan find() wordt doorgegeven moet overeenkomen met die in de index. Als de index is genormaliseerd naar kleine letters, dan dient alle tekst die aan find() wordt doorgegeven worden onderworpen aan strtolower(), anders worden mogelijk geen resultaten gevonden.

12.3.2. Zoek resultaten

Het zoek resultaat is een array van Zend_Search_Lucene_Search_QueryHit objecten. Ieder van deze objecten heeft twee eigenschappen: $hit->document is een documentnummer binnen de index en $hit->score is een score van het resultaat binnen het volledige zoekresultaat. Resultaat wordt geordend op score (hoogste score komt eerst).

Het Zend_Search_Lucene_Search_QueryHit object bied daarnaast ook ieder veld van het gevonden Zend_Search_Lucene_Document als een eigenschap. In het volgende voorbeeld wordt een resultaat teruggegeven en heeft het document twee velden: title en author.

<?php

require_once('Zend/Search/Lucene.php');

$index = new Zend_Search_Lucene('/data/my_index');

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

foreach ($hits as $hit) {
    echo $hit->id;
    echo $hit->score;

    echo $hit->title;
    echo $hit->author;
}

?>

Het originele Zend_Search_Lucene_Document object kan ook worden teruggegeven vanuit de Zend_Search_Lucene_Search_QueryHit. Je kan geindexeerde delen van het document verkrijgen door gebruik te maken van de getDocument()methode van het index object en dan de getFieldValue() methode te gebruiken:

<?php

require_once('Zend/Search/Lucene.php');

$index = new Zend_Search_Lucene('/data/my_index');

$hits = $index->find($query);
foreach ($hits as $hit) {
    // geef een Zend_Search_Lucene_Document object terug voor dit resultaat
    echo $document = $hit->getDocument();

    // geef een Zend_Search_Lucene_Field object terug
    // uit het Zend_Search_Lucene_Document
    echo $document->getField('title');

    // geef de string waarde terug van een Zend_Search_Lucene_Field object
    echo $document->getFieldValue('title');

    // hetzelfde als getFieldValue()
    echo $document->title;
}

?>

De velden die beschikbaar zijn via het Zend_Search_Lucene_Document object worden besloten tijdens het indexeren. De document velden worden ofwel geindexeerd, ofwel geindexeerd en opgeslagen, in het document door de indexeringsapplicatie (bijvoorbeeld LuceneIndexCreation.jar).

Let op dat de document identiteit ('path' in het voorbeeld) ook wordt opgeslagen in de index en vanuit de index opgehaald dient te worden.

12.3.3. Resultaten Scoring

Zend_Search_Lucene gebruikt hetzelfde score algoritme als Java Lucene. Zoek resultaten worden geordend op score, met de hoogste score als eerst.

Een verschillende score betekent dat een document meer overeenkomt met de zoekopdracht dan de andere.

Ruwweg genomen wordt de zoekopdracht vaker gevonden in documenten met een hogere score dan in documenten met een lagere score.

Score kan worden verkregen via de score eigenschap van het resultaat:

<?php
$hits = $index->find($query);

foreach ($hits as $hit) {
    echo $hit->id;
    echo $hit->score;
}

?>

Zend_Search_Lucene_Search_Similarity klasse wordt gebruikt om de score te berekenen. Zie Uitbreidbaarheid. Scoring Algoritmes sectie voor details.