X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/70f154be8b69d3b57eebd25eff225ee29ccc97ba..1147b83b22a073db2f81ea177f9caa12e727e249:/lib-php/tokenizer/legacy_icu_tokenizer.php diff --git a/lib-php/tokenizer/legacy_icu_tokenizer.php b/lib-php/tokenizer/legacy_icu_tokenizer.php index 314bd27e..ca224a22 100644 --- a/lib-php/tokenizer/legacy_icu_tokenizer.php +++ b/lib-php/tokenizer/legacy_icu_tokenizer.php @@ -2,13 +2,14 @@ namespace Nominatim; +require_once(CONST_LibDir.'/SimpleWordList.php'); + class Tokenizer { private $oDB; private $oNormalizer; private $oTransliterator; - private $aCountryRestriction; public function __construct(&$oDB) { @@ -19,23 +20,17 @@ class Tokenizer public function checkStatus() { - $sSQL = "SELECT word_id FROM word WHERE word_token IN (' a')"; + $sSQL = 'SELECT word_id FROM word WHERE word_id is not null limit 1'; $iWordID = $this->oDB->getOne($sSQL); if ($iWordID === false) { - throw new Exception('Query failed', 703); + throw new \Exception('Query failed', 703); } if (!$iWordID) { - throw new Exception('No value', 704); + throw new \Exception('No value', 704); } } - public function setCountryRestriction($aCountries) - { - $this->aCountryRestriction = $aCountries; - } - - public function normalizeString($sTerm) { if ($this->oNormalizer === null) { @@ -55,9 +50,8 @@ class Tokenizer { $aResults = array(); - $sSQL = 'SELECT word_id, class, type FROM word '; - $sSQL .= ' WHERE word_token = \' \' || :term'; - $sSQL .= ' AND class is not null AND class not in (\'place\')'; + $sSQL = "SELECT word_id, info->>'class' as class, info->>'type' as type "; + $sSQL .= ' FROM word WHERE word_token = :term and type = \'S\''; Debug::printVar('Term', $sTerm); Debug::printSQL($sSQL); @@ -89,13 +83,10 @@ class Tokenizer $sNormQuery .= ','.$this->normalizeString($oPhrase->getPhrase()); $sPhrase = $this->makeStandardWord($oPhrase->getPhrase()); Debug::printVar('Phrase', $sPhrase); - if (strlen($sPhrase) > 0) { - $aWords = explode(' ', $sPhrase); - Tokenizer::addTokens($aTokens, $aWords); - $aWordLists[] = $aWords; - } else { - $aWordLists[] = array(); - } + + $oWordList = new SimpleWordList($sPhrase); + $aTokens = array_merge($aTokens, $oWordList->getTokens()); + $aWordLists[] = $oWordList; } Debug::printVar('Tokens', $aTokens); @@ -104,7 +95,7 @@ class Tokenizer $oValidTokens = $this->computeValidTokens($aTokens, $sNormQuery); foreach ($aPhrases as $iPhrase => $oPhrase) { - $oPhrase->computeWordSets($aWordLists[$iPhrase], $oValidTokens); + $oPhrase->setWordSets($aWordLists[$iPhrase]->getWordSets($oValidTokens)); } return $oValidTokens; @@ -146,10 +137,9 @@ class Tokenizer private function addTokensFromDB(&$oValidTokens, $aTokens, $sNormQuery) { // Check which tokens we have, get the ID numbers - $sSQL = 'SELECT word_id, word_token, type'; - $sSQL .= " info->>'cc' as country, info->>'postcode' as postcode,"; + $sSQL = 'SELECT word_id, word_token, type, word,'; $sSQL .= " info->>'op' as operator,"; - $sSQL .= " info->>'class' as class, info->>'type' as type,"; + $sSQL .= " info->>'class' as class, info->>'type' as ctype,"; $sSQL .= " info->>'count' as count"; $sSQL .= ' FROM word WHERE word_token in ('; $sSQL .= join(',', $this->oDB->getDBQuotedList($aTokens)).')'; @@ -160,88 +150,62 @@ class Tokenizer foreach ($aDBWords as $aWord) { $iId = (int) $aWord['word_id']; + $sTok = $aWord['word_token']; switch ($aWord['type']) { - 'C': // country name tokens - if ($aWord['country'] === null - || ($this->aCountryRestriction - && !in_array($aWord['country'], $this->aCountryRestriction)) - ) { - continue; + case 'C': // country name tokens + if ($aWord['word'] !== null) { + $oValidTokens->addToken( + $sTok, + new Token\Country($iId, $aWord['word']) + ); } - $oToken = new Token\Country($iId, $aWord['country']) break; - 'H': // house number tokens - $oToken = new Token\HouseNumber($iId, $aWord['word_token']); + case 'H': // house number tokens + $oValidTokens->addToken($sTok, new Token\HouseNumber($iId, $aWord['word_token'])); break; - 'P': // postcode tokens + case 'P': // postcode tokens // Postcodes are not normalized, so they may have content // that makes SQL injection possible. Reject postcodes // that would need special escaping. - if ($aWord['postcode'] === null - || pg_escape_string($aWord['postcode']) == $aWord['postcode'] + if ($aWord['word'] !== null + && pg_escape_string($aWord['word']) == $aWord['word'] ) { - continue; - } - $sNormPostcode = $this->normalizeString($aWord['postcode']); - if (strpos($sNormQuery, $sNormPostcode) === false) { - continue; + $sNormPostcode = $this->normalizeString($aWord['word']); + if (strpos($sNormQuery, $sNormPostcode) !== false) { + $oValidTokens->addToken( + $sTok, + new Token\Postcode($iId, $aWord['word'], null) + ); + } } - $oToken = new Token\Postcode($iId, $aWord['postcode'], null); break; - 'S': // tokens for classification terms (special phrases) - if ($aWord['class'] === null || $aWord['type'] === null - ) { - continue; + case 'S': // tokens for classification terms (special phrases) + if ($aWord['class'] !== null && $aWord['ctype'] !== null) { + $oValidTokens->addToken($sTok, new Token\SpecialTerm( + $iId, + $aWord['class'], + $aWord['ctype'], + (isset($aWord['operator'])) ? Operator::NEAR : Operator::NONE + )); } - $oToken = new Token\SpecialTerm( - $iId, - $aWord['class'], - $aWord['type'], - $aWord['op'] ? Operator::NEAR : Operator::NONE - ); break; - 'W': // full-word tokens - $oToken = new Token\Word( + case 'W': // full-word tokens + $oValidTokens->addToken($sTok, new Token\Word( $iId, (int) $aWord['count'], substr_count($aWord['word_token'], ' ') - ); + )); break; - 'w': // partial word terms - $oToken = new Token\Partial( + case 'w': // partial word terms + $oValidTokens->addToken($sTok, new Token\Partial( $iId, $aWord['word_token'], (int) $aWord['count'] - ); + )); break; default: - continue; - } - - $oValidTokens->addToken($aWord['word_token'], $oToken); - } - } - - - /** - * Add the tokens from this phrase to the given list of tokens. - * - * @param string[] $aTokens List of tokens to append. - * - * @return void - */ - private static function addTokens(&$aTokens, $aWords) - { - $iNumWords = count($aWords); - - for ($i = 0; $i < $iNumWords; $i++) { - $sPhrase = $aWords[$i]; - $aTokens[$sPhrase] = $sPhrase; - - for ($j = $i + 1; $j < $iNumWords; $j++) { - $sPhrase .= ' '.$aWords[$j]; - $aTokens[$sPhrase] = $sPhrase; + break; } } }