Question

I have something similar to the following code:

[...]
while($result=mysql_fetch_assoc($query)){
    //Build a doc
    $doc = new Zend_Search_Lucene_Document();

    [...]

    $doc->addField(Zend_Search_Lucene_Field::text('category', sanitize($result["category"])));
    $all_values=explode(',',$result["value"]);
    $i=0;
    foreach ($all_values as $value) {
        $doc->addField(Zend_Search_Lucene_Field::text('value_'.($i++), urlencode($value)));
    }

    [...]

    //Add to doc
    $index->addDocument($doc);
}
[...]

Now I would like to show only the field value_... which have the greater score after a search.

How could I do it?

Was it helpful?

Solution

After thinking a bit more on this, I've got a solution to my problem.

Zend Lucene orders the results by score and so, what I need to do is create a doc for each $value of the foreach loop and then, create an index for the ID of my current result (called res_id) that is inside of the foreach. This way, i can programatically show only one result of the same res_id after a search.

So my code becomes:

[...]
while($result=mysql_fetch_assoc($query)){
    $all_values=explode(',',$result["value"]);
    //Create a Doc foreach value of $all_values and gave them the same category of the result of the query
    foreach ($all_values as $value) {
        //Build a doc
        $doc = new Zend_Search_Lucene_Document();

        [...]

        //Added res_id just to help grouping the results
        $doc->addField(Zend_Search_Lucene_Field::unIndexed('res_id', sanitize($result["id"])));

        $doc->addField(Zend_Search_Lucene_Field::text('category', sanitize($result["category"])));
        //Renamed the field to value
        $doc->addField(Zend_Search_Lucene_Field::text('value', urlencode($value)));

        [...]

        //Add to doc
        $index->addDocument($doc);
    }
}
[...]

Now, when I make a search, I show only the first occurrence of res_id (the one that have more score).

Here's the code that I have on my Controller that sends to the view an array with the items and the total items found:

[...]
public function indexAction()
{
    $this->view->query=urldecode($this->_getParam("query"));
    if ($this->view->query){
        //open the index
        $index = new Zend_Search_Lucene('path/to/lucene/index');
        $hits = $index->find($this->view->query);
        $executed_ids=array();
        $total=0;
        $this->view->items=array();
        foreach ($hits as $hit) {
            //Pass item to view only if it is not listed yet on $executed_ids
            if (!$executed_ids[$hit->res_id]){
                $this->view->items[]=$hit;
                $executed_ids[$hit->res_id]=true;
                $total++;
            }
        }
        $this->view->total_hits=$total;
    }
}
[...]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top