]> git.openstreetmap.org Git - nominatim.git/blobdiff - lib-php/SearchDescription.php
always ignore multi term partials in search
[nominatim.git] / lib-php / SearchDescription.php
index ea9d7f58feb5dd06b453033f39ac1ec446f13e31..8da49a9ff0bfc7d2d0343d21391462e8baa95b2b 100644 (file)
@@ -179,6 +179,7 @@ class SearchDescription
                 // - increase score for finding it anywhere else (optimisation)
                 if (!$bLastToken) {
                     $oSearch->iSearchRank += 5;
+                    $oSearch->iNamePhrase = -1;
                 }
                 $aNewSearches[] = $oSearch;
             }
@@ -205,6 +206,7 @@ class SearchDescription
                 ) {
                     $oSearch = clone $this;
                     $oSearch->iSearchRank++;
+                    $oSearch->iNamePhrase = -1;
                     if (strlen($oSearchTerm->sPostcode) < 4) {
                         $oSearch->iSearchRank += 4 - strlen($oSearchTerm->sPostcode);
                     }
@@ -218,7 +220,11 @@ class SearchDescription
             if (!$this->sHouseNumber && $this->iOperator != Operator::POSTCODE) {
                 $oSearch = clone $this;
                 $oSearch->iSearchRank++;
+                $oSearch->iNamePhrase = -1;
                 $oSearch->sHouseNumber = $oSearchTerm->sToken;
+                if ($this->iOperator != Operator::NONE) {
+                    $oSearch->iSearchRank++;
+                }
                 // sanity check: if the housenumber is not mainly made
                 // up of numbers, add a penalty
                 if (preg_match('/\\d/', $oSearch->sHouseNumber) === 0
@@ -255,7 +261,8 @@ class SearchDescription
         ) {
             if ($this->iOperator == Operator::NONE) {
                 $oSearch = clone $this;
-                $oSearch->iSearchRank++;
+                $oSearch->iSearchRank += 2;
+                $oSearch->iNamePhrase = -1;
 
                 $iOp = $oSearchTerm->iOperator;
                 if ($iOp == Operator::NONE) {
@@ -265,6 +272,11 @@ class SearchDescription
                         $iOp = Operator::NEAR;
                     }
                     $oSearch->iSearchRank += 2;
+                } elseif (!$bFirstToken && !$bLastToken) {
+                    $oSearch->iSearchRank += 2;
+                }
+                if ($this->sHouseNumber) {
+                    $oSearch->iSearchRank++;
                 }
 
                 $oSearch->setPoiSearch(
@@ -285,11 +297,12 @@ class SearchDescription
             if (!empty($this->aName) || !($bFirstPhrase || $sPhraseType == '')) {
                 if (($sPhraseType == '' || !$bFirstPhrase) && !$bHasPartial) {
                     $oSearch = clone $this;
+                    $oSearch->iNamePhrase = -1;
                     $oSearch->iSearchRank += 3 * $oSearchTerm->iTermCount;
                     $oSearch->aAddress[$iWordID] = $iWordID;
                     $aNewSearches[] = $oSearch;
                 }
-            } else {
+            } elseif (empty($this->aNameNonSearch)) {
                 $oSearch = clone $this;
                 $oSearch->iSearchRank++;
                 $oSearch->aName = array($iWordID => $iWordID);
@@ -320,7 +333,9 @@ class SearchDescription
     public function extendWithPartialTerm($sToken, $oSearchTerm, $bStructuredPhrases, $iPhrase, $aFullTokens)
     {
         // Only allow name terms.
-        if (!(is_a($oSearchTerm, '\Nominatim\Token\Word'))) {
+        if (!(is_a($oSearchTerm, '\Nominatim\Token\Word'))
+            || strpos($sToken, ' ') !== false
+        ) {
             return array();
         }
 
@@ -329,51 +344,33 @@ class SearchDescription
 
         if ((!$bStructuredPhrases || $iPhrase > 0)
             && (!empty($this->aName))
-            && strpos($sToken, ' ') === false
         ) {
+            $oSearch = clone $this;
+            $oSearch->iSearchRank++;
+            if (preg_match('#^[0-9 ]+$#', $sToken)) {
+                $oSearch->iSearchRank++;
+            }
             if ($oSearchTerm->iSearchNameCount < CONST_Max_Word_Frequency) {
-                $oSearch = clone $this;
-                $oSearch->iSearchRank += $oSearchTerm->iTermCount + 1;
-                if (empty($this->aName)) {
-                    $oSearch->iSearchRank++;
-                }
-                if (preg_match('#^[0-9]+$#', $sToken)) {
-                    $oSearch->iSearchRank++;
-                }
                 $oSearch->aAddress[$iWordID] = $iWordID;
-                $aNewSearches[] = $oSearch;
             } else {
-                $oSearch = clone $this;
-                $oSearch->iSearchRank += $oSearchTerm->iTermCount + 1;
                 $oSearch->aAddressNonSearch[$iWordID] = $iWordID;
                 if (!empty($aFullTokens)) {
                     $oSearch->iSearchRank++;
                 }
-                $aNewSearches[] = $oSearch;
-
-                // revert to the token version?
-                foreach ($aFullTokens as $oSearchTermToken) {
-                    if (is_a($oSearchTermToken, '\Nominatim\Token\Word')) {
-                        $oSearch = clone $this;
-                        $oSearch->iSearchRank += 3;
-                        $oSearch->aAddress[$oSearchTermToken->iId]
-                            = $oSearchTermToken->iId;
-                        $aNewSearches[] = $oSearch;
-                    }
-                }
             }
+            $aNewSearches[] = $oSearch;
         }
 
         if ((!$this->sPostcode && !$this->aAddress && !$this->aAddressNonSearch)
-            && (empty($this->aName) || $this->iNamePhrase == $iPhrase)
+            && ((empty($this->aName) && empty($this->aNameNonSearch)) || $this->iNamePhrase == $iPhrase)
         ) {
             $oSearch = clone $this;
-            $oSearch->iSearchRank += 2;
-            if (empty($this->aName)) {
-                $oSearch->iSearchRank += 1;
+            $oSearch->iSearchRank++;
+            if (empty($this->aName) && empty($this->aNameNonSearch)) {
+                $oSearch->iSearchRank++;
             }
-            if (preg_match('#^[0-9]+$#', $sToken)) {
-                $oSearch->iSearchRank += 2;
+            if (preg_match('#^[0-9 ]+$#', $sToken)) {
+                $oSearch->iSearchRank++;
             }
             if ($oSearchTerm->iSearchNameCount < CONST_Max_Word_Frequency) {
                 if (empty($this->aName)
@@ -387,6 +384,9 @@ class SearchDescription
                 }
                 $oSearch->aName[$iWordID] = $iWordID;
             } else {
+                if (!empty($aFullTokens)) {
+                    $oSearch->iSearchRank++;
+                }
                 $oSearch->aNameNonSearch[$iWordID] = $iWordID;
             }
             $oSearch->iNamePhrase = $iPhrase;
@@ -615,14 +615,14 @@ class SearchDescription
         // too many results are expected for the street, i.e. if the result
         // will be narrowed down by an address. Remeber that with ordering
         // every single result has to be checked.
-        if ($this->sHouseNumber && (!empty($this->aAddress) || $this->sPostcode)) {
+        if ($this->sHouseNumber && ($this->bRareName || !empty($this->aAddress) || $this->sPostcode)) {
             $sHouseNumberRegex = '\\\\m'.$this->sHouseNumber.'\\\\M';
             $aOrder[] = ' (';
             $aOrder[0] .= 'EXISTS(';
             $aOrder[0] .= '  SELECT place_id';
             $aOrder[0] .= '  FROM placex';
             $aOrder[0] .= '  WHERE parent_place_id = search_name.place_id';
-            $aOrder[0] .= "    AND transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
+            $aOrder[0] .= "    AND housenumber ~* E'".$sHouseNumberRegex."'";
             $aOrder[0] .= '  LIMIT 1';
             $aOrder[0] .= ') ';
             // also housenumbers from interpolation lines table are needed
@@ -752,7 +752,7 @@ class SearchDescription
         $sHouseNumberRegex = '\\\\m'.$this->sHouseNumber.'\\\\M';
         $sSQL = 'SELECT place_id FROM placex ';
         $sSQL .= 'WHERE parent_place_id in ('.$sPlaceIDs.')';
-        $sSQL .= "  AND transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
+        $sSQL .= "  AND housenumber ~* E'".$sHouseNumberRegex."'";
         $sSQL .= $this->oContext->excludeSQL(' AND place_id');
 
         Debug::printSQL($sSQL);
@@ -791,20 +791,6 @@ class SearchDescription
             }
         }
 
-        // If nothing found try the aux fallback table
-        if (CONST_Use_Aux_Location_data && empty($aResults)) {
-            $sSQL = 'SELECT place_id FROM location_property_aux';
-            $sSQL .= ' WHERE parent_place_id in ('.$sPlaceIDs.')';
-            $sSQL .= " AND housenumber = '".$this->sHouseNumber."'";
-            $sSQL .= $this->oContext->excludeSQL(' AND place_id');
-
-            Debug::printSQL($sSQL);
-
-            foreach ($oDB->getCol($sSQL) as $iPlaceId) {
-                $aResults[$iPlaceId] = new Result($iPlaceId, Result::TABLE_AUX);
-            }
-        }
-
         // If nothing found then search in Tiger data (location_property_tiger)
         if (CONST_Use_US_Tiger_Data && $bIsIntHouseNumber && empty($aResults)) {
             $sSQL = 'SELECT place_id FROM location_property_tiger';