Parcourir la source

Zend_Search_Lucene: ability to sort search results by score _and_ other stored fields. Closes ZF-8311.

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@19011 44c647ce-9c0f-0410-b52a-842ac1e357ba
alexander il y a 16 ans
Parent
commit
8dfd97e1ea
2 fichiers modifiés avec 53 ajouts et 16 suppressions
  1. 20 16
      library/Zend/Search/Lucene.php
  2. 33 0
      tests/Zend/Search/Lucene/Search23Test.php

+ 20 - 16
library/Zend/Search/Lucene.php

@@ -987,28 +987,32 @@ class Zend_Search_Lucene implements Zend_Search_Lucene_Interface
                     throw new Zend_Search_Lucene_Exception('Field name must be a string.');
                     throw new Zend_Search_Lucene_Exception('Field name must be a string.');
                 }
                 }
 
 
-                if (!in_array($fieldName, $fieldNames)) {
-                    throw new Zend_Search_Lucene_Exception('Wrong field name.');
-                }
+                if (strtolower($fieldName) == 'score') {
+                    $sortArgs[] = $scores;
+                } else {
+                    if (!in_array($fieldName, $fieldNames)) {
+                        throw new Zend_Search_Lucene_Exception('Wrong field name.');
+                    }
 
 
-                $valuesArray = array();
-                foreach ($hits as $hit) {
-                    try {
-                        $value = $hit->getDocument()->getFieldValue($fieldName);
-                    } catch (Zend_Search_Lucene_Exception $e) {
-                        if (strpos($e->getMessage(), 'not found') === false) {
-                            throw $e;
-                        } else {
-                            $value = null;
+                    $valuesArray = array();
+                    foreach ($hits as $hit) {
+                        try {
+                            $value = $hit->getDocument()->getFieldValue($fieldName);
+                        } catch (Zend_Search_Lucene_Exception $e) {
+                            if (strpos($e->getMessage(), 'not found') === false) {
+                                throw $e;
+                            } else {
+                                $value = null;
+                            }
                         }
                         }
+
+                        $valuesArray[] = $value;
                     }
                     }
 
 
-                    $valuesArray[] = $value;
+                    $sortArgs[] = &$valuesArray;
+                    unset($valuesArray);
                 }
                 }
 
 
-                $sortArgs[] = &$valuesArray;
-                unset($valuesArray);
-
                 if ($count + 1 < count($argList)  &&  is_integer($argList[$count+1])) {
                 if ($count + 1 < count($argList)  &&  is_integer($argList[$count+1])) {
                     $count++;
                     $count++;
                     $sortArgs[] = &$argList[$count];
                     $sortArgs[] = &$argList[$count];

+ 33 - 0
tests/Zend/Search/Lucene/Search23Test.php

@@ -525,6 +525,39 @@ class Zend_Search_Lucene_Search23Test extends PHPUnit_Framework_TestCase
         }
         }
     }
     }
 
 
+    public function testSortingResultByScore()
+    {
+        $index = Zend_Search_Lucene::open(dirname(__FILE__) . '/_index23Sample/_files');
+
+        $hits = $index->find('"reporting bugs"', 'score', SORT_NUMERIC, SORT_ASC,
+                                                 'path',  SORT_STRING,  SORT_ASC);
+        $this->assertEquals(count($hits), 4);
+        $expectedResultset = array(array(2, 0.176996, 'IndexSource/contributing.patches.html'),
+                                   array(7, 0.212395, 'IndexSource/contributing.bugs.html'),
+                                   array(8, 0.212395, 'IndexSource/contributing.html'),
+                                   array(0, 0.247795, 'IndexSource/contributing.documentation.html'));
+
+        foreach ($hits as $resId => $hit) {
+            $this->assertEquals($hit->id, $expectedResultset[$resId][0]);
+            $this->assertTrue( abs($hit->score - $expectedResultset[$resId][1]) < 0.000001 );
+            $this->assertEquals($hit->path, $expectedResultset[$resId][2]);
+        }
+
+        $hits = $index->find('"reporting bugs"', 'score', SORT_NUMERIC, SORT_ASC,
+                                                 'path',  SORT_STRING,  SORT_DESC);
+        $this->assertEquals(count($hits), 4);
+        $expectedResultset = array(array(2, 0.176996, 'IndexSource/contributing.patches.html'),
+                                   array(8, 0.212395, 'IndexSource/contributing.html'),
+                                   array(7, 0.212395, 'IndexSource/contributing.bugs.html'),
+                                   array(0, 0.247795, 'IndexSource/contributing.documentation.html'));
+
+        foreach ($hits as $resId => $hit) {
+            $this->assertEquals($hit->id, $expectedResultset[$resId][0]);
+            $this->assertTrue( abs($hit->score - $expectedResultset[$resId][1]) < 0.000001 );
+            $this->assertEquals($hit->path, $expectedResultset[$resId][2]);
+        }
+    }
+
     public function testLimitingResult()
     public function testLimitingResult()
     {
     {
         $index = Zend_Search_Lucene::open(dirname(__FILE__) . '/_index23Sample/_files');
         $index = Zend_Search_Lucene::open(dirname(__FILE__) . '/_index23Sample/_files');