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?
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;
}
}
[...]