public function testLimitingResult() { $index = Lucene\Lucene::open(__DIR__ . '/_index23Sample/_files'); $storedResultSetLimit = Lucene\Lucene::getResultSetLimit(); Lucene\Lucene::setResultSetLimit(3); $hits = $index->find('"reporting bugs"', 'path'); $this->assertEquals(count($hits), 3); $expectedResultset = array(array(7, 0.212395, 'IndexSource/contributing.bugs.html'), array(0, 0.247795, 'IndexSource/contributing.documentation.html'), array(2, 0.176996, 'IndexSource/contributing.patches.html')); foreach ($hits as $resId => $hit) { $this->assertEquals($hit->id, $expectedResultset[$resId][0]); $this->assertTrue(abs($hit->score - $expectedResultset[$resId][1]) < 1.0E-6); $this->assertEquals($hit->path, $expectedResultset[$resId][2]); } Lucene\Lucene::setResultSetLimit($storedResultSetLimit); }
/** * Performs a query against the index and returns an array * of Zend_Search_Lucene_Search_QueryHit objects. * Input is a string or Zend_Search_Lucene_Search_Query. * * @param \ZendSearch\Lucene\Search\QueryParser|string $query * @return array|\ZendSearch\Lucene\Search\QueryHit * @throws \ZendSearch\Lucene\Exception\InvalidArgumentException * @throws \ZendSearch\Lucene\Exception\RuntimeException */ public function find($query) { if (is_string($query)) { $query = Search\QueryParser::parse($query); } elseif (!$query instanceof Search\Query\AbstractQuery) { throw new InvalidArgumentException('Query must be a string or ZendSearch\\Lucene\\Search\\Query object'); } $this->commit(); $hits = array(); $scores = array(); $ids = array(); $query = $query->rewrite($this)->optimize($this); $query->execute($this); $topScore = 0; $resultSetLimit = Lucene::getResultSetLimit(); foreach ($query->matchedDocs() as $id => $num) { $docScore = $query->score($id, $this); if ($docScore != 0) { $hit = new Search\QueryHit($this); $hit->document_id = $hit->id = $id; $hit->score = $docScore; $hits[] = $hit; $ids[] = $id; $scores[] = $docScore; if ($docScore > $topScore) { $topScore = $docScore; } } if ($resultSetLimit != 0 && count($hits) >= $resultSetLimit) { break; } } if (count($hits) == 0) { // skip sorting, which may cause a error on empty index return array(); } if ($topScore > 1) { foreach ($hits as $hit) { $hit->score /= $topScore; } } if (func_num_args() == 1) { // sort by scores array_multisort($scores, SORT_DESC, SORT_NUMERIC, $ids, SORT_ASC, SORT_NUMERIC, $hits); } else { // sort by given field names $argList = func_get_args(); $fieldNames = $this->getFieldNames(); $sortArgs = array(); // PHP 5.3 now expects all arguments to array_multisort be passed by // reference (if it's invoked through call_user_func_array()); // since constants can't be passed by reference, create some placeholder variables. $sortReg = SORT_REGULAR; $sortAsc = SORT_ASC; $sortNum = SORT_NUMERIC; $sortFieldValues = array(); for ($count = 1; $count < count($argList); $count++) { $fieldName = $argList[$count]; if (!is_string($fieldName)) { throw new RuntimeException('Field name must be a string.'); } if (strtolower($fieldName) == 'score') { $sortArgs[] =& $scores; } else { if (!in_array($fieldName, $fieldNames)) { throw new RuntimeException('Wrong field name.'); } if (!isset($sortFieldValues[$fieldName])) { $valuesArray = array(); foreach ($hits as $hit) { try { $value = $hit->getDocument()->getFieldValue($fieldName); } catch (\Exception $e) { if (strpos($e->getMessage(), 'not found') === false) { throw new RuntimeException($e->getMessage(), $e->getCode(), $e); } else { $value = null; } } $valuesArray[] = $value; } // Collect loaded values in $sortFieldValues // Required for PHP 5.3 which translates references into values when source // variable is destroyed $sortFieldValues[$fieldName] = $valuesArray; } $sortArgs[] =& $sortFieldValues[$fieldName]; } if ($count + 1 < count($argList) && is_integer($argList[$count + 1])) { $count++; $sortArgs[] =& $argList[$count]; if ($count + 1 < count($argList) && is_integer($argList[$count + 1])) { $count++; $sortArgs[] =& $argList[$count]; } else { if ($argList[$count] == SORT_ASC || $argList[$count] == SORT_DESC) { $sortArgs[] =& $sortReg; } else { $sortArgs[] =& $sortAsc; } } } else { $sortArgs[] =& $sortAsc; $sortArgs[] =& $sortReg; } } // Sort by id's if values are equal $sortArgs[] =& $ids; $sortArgs[] =& $sortAsc; $sortArgs[] =& $sortNum; // Array to be sorted $sortArgs[] =& $hits; // Do sort call_user_func_array('array_multisort', $sortArgs); } return $hits; }