private $sCountryCode = '';
/// List of word ids making up the name of the object.
private $aName = array();
+ /// True if the name is rare enough to force index use on name.
+ private $bRareName = false;
/// List of word ids making up the address of the object.
private $aAddress = array();
/// Subset of word ids of full words making up the address.
$oSearch = clone $this;
$oSearch->iSearchRank++;
$oSearch->aName = array($iWordID => $iWordID);
+ if (CONST_Search_NameOnlySearchFrequencyThreshold) {
+ $oSearch->bRareName =
+ $aSearchTerm['search_name_count'] + 1
+ < CONST_Search_NameOnlySearchFrequencyThreshold;
+ }
$aNewSearches[] = $oSearch;
}
}
$oSearch->iSearchRank += 2;
}
if ($aSearchTerm['search_name_count'] + 1 < CONST_Max_Word_Frequency) {
+ if (empty($this->aName) && CONST_Search_NameOnlySearchFrequencyThreshold) {
+ $oSearch->bRareName =
+ $aSearchTerm['search_name_count'] + 1
+ < CONST_Search_NameOnlySearchFrequencyThreshold;
+ } else {
+ $oSearch->bRareName = false;
+ }
$oSearch->aName[$iWordID] = $iWordID;
} else {
$oSearch->aNameNonSearch[$iWordID] = $iWordID;
/**
* Query database for places that match this search.
*
- * @param object $oDB Database connection to use.
- * @param mixed[] $aWordFrequencyScores Number of times tokens appears
- * overall in a planet database.
- * @param integer $iMinRank Minimum address rank to restrict
- * search to.
- * @param integer $iMaxRank Maximum address rank to restrict
- * search to.
- * @param integer $iLimit Maximum number of results.
+ * @param object $oDB Database connection to use.
+ * @param integer $iMinRank Minimum address rank to restrict search to.
+ * @param integer $iMaxRank Maximum address rank to restrict search to.
+ * @param integer $iLimit Maximum number of results.
*
* @return mixed[] An array with two fields: IDs contains the list of
* matching place IDs and houseNumber the houseNumber
* if appicable or -1 if not.
*/
- public function query(&$oDB, &$aWordFrequencyScores, $iMinRank, $iMaxRank, $iLimit)
+ public function query(&$oDB, $iMinRank, $iMaxRank, $iLimit)
{
$aResults = array();
$iHousenumber = -1;
// First search for places according to name and address.
$aResults = $this->queryNamedPlace(
$oDB,
- $aWordFrequencyScores,
$iMinRank,
$iMaxRank,
$iLimit
//now search for housenumber, if housenumber provided
if ($this->sHouseNumber && !empty($aResults)) {
$aNamedPlaceIDs = $aResults;
- $aResults = $this->queryHouseNumber($oDB, $aNamedPlaceIDs, $iLimit);
+ $aResults = $this->queryHouseNumber($oDB, $aNamedPlaceIDs);
if (empty($aResults) && $this->looksLikeFullAddress()) {
$aResults = $aNamedPlaceIDs;
return $aResults;
}
- private function queryNamedPlace(&$oDB, $aWordFrequencyScores, $iMinAddressRank, $iMaxAddressRank, $iLimit)
+ private function queryNamedPlace(&$oDB, $iMinAddressRank, $iMaxAddressRank, $iLimit)
{
$aTerms = array();
$aOrder = array();
- if ($this->sHouseNumber && !empty($this->aAddress)) {
+ // Sort by existence of the requested house number but only if not
+ // 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)) {
$sHouseNumberRegex = '\\\\m'.$this->sHouseNumber.'\\\\M';
$aOrder[] = ' (';
$aOrder[0] .= 'EXISTS(';
}
if (!empty($this->aAddress)) {
// For infrequent name terms disable index usage for address
- if (CONST_Search_NameOnlySearchFrequencyThreshold
- && count($this->aName) == 1
- && $aWordFrequencyScores[$this->aName[reset($this->aName)]]
- < CONST_Search_NameOnlySearchFrequencyThreshold
- ) {
+ if ($this->bRareName) {
$aTerms[] = 'array_cat(nameaddress_vector,ARRAY[]::integer[]) @> '.getArraySQL($this->aAddress);
} else {
$aTerms[] = 'nameaddress_vector @> '.getArraySQL($this->aAddress);
return $aResults;
}
- private function queryHouseNumber(&$oDB, $aRoadPlaceIDs, $iLimit)
+ private function queryHouseNumber(&$oDB, $aRoadPlaceIDs)
{
$aResults = array();
$sPlaceIDs = Result::joinIdsByTable($aRoadPlaceIDs, Result::TABLE_PLACEX);
$sSQL .= 'WHERE parent_place_id in ('.$sPlaceIDs.')';
$sSQL .= " AND transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
- $sSQL .= " LIMIT $iLimit";
Debug::printSQL($sSQL);
$sSQL .= $iHousenumber.'>=startnumber and ';
$sSQL .= $iHousenumber.'<=endnumber';
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
- $sSQL .= " limit $iLimit";
Debug::printSQL($sSQL);
$sSQL .= ' WHERE parent_place_id in ('.$sPlaceIDs.')';
$sSQL .= " AND housenumber = '".$this->sHouseNumber."'";
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
- $sSQL .= " limit $iLimit";
Debug::printSQL($sSQL);
$sSQL .= $iHousenumber.'>=startnumber and ';
$sSQL .= $iHousenumber.'<=endnumber';
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
- $sSQL .= " limit $iLimit";
Debug::printSQL($sSQL);