private function _calculateRelevancy(){ // Lowercase it. $query = strtolower($this->query); // Convert this string to latin. $query = \Core\str_to_latin($query); // Skip punctuation. $query = preg_replace('/[^a-z0-9 ]/', '', $query); // Split out words. $parts = explode(' ', $query); $ignore = Helper::GetSkipWords(); foreach($parts as $k => $word){ // Skip blank words. if(!$word){ unset($parts[$k]); continue; } // Unset any to-be-skipped word. if(in_array($word, $ignore)){ unset($parts[$k]); continue; } } // All query words in the result mean 100% relevancy. $size = sizeof($parts); if(!$size){ $this->relevancy = 0; return; } $wordweight = 100 / $size; // And each word has 3 parts to it. $wordweight /= 3; $rel = 0.0; $str = explode(' ', $this->_model->get('search_index_str')); $pri = explode(' ', $this->_model->get('search_index_pri')); $sec = explode(' ', $this->_model->get('search_index_sec')); foreach($parts as $word){ $it = new DoubleMetaPhone($word); if(in_array($word, $str)){ // Exact matches here get an automatic boost! $rel += ($wordweight * 3); } else{ foreach($str as $w){ if(strpos($w, $word) !== false){ // If a partial match is located, add a fraction of the word weight, (since it wasn't a complete match). $rel += $wordweight * (strlen($word) / strlen($w)); break; } } } if(in_array($it->primary, $pri)) $rel += $wordweight; if(in_array($it->secondary, $sec)) $rel += $wordweight; } $this->relevancy = min($rel, 100); }
/** * Translate a query string to a populated where clause based on the search index criteria. * * @param string $query * * @return DatasetWhereClause */ public static function GetWhereClause($query){ $subwhere = new DatasetWhereClause('search'); $subwhere->setSeparator('or'); // Lowercase it. $query = strtolower($query); // Convert this string to latin. $query = \Core\str_to_latin($query); // Skip punctuation. $query = preg_replace('/[^a-z0-9 ]/', '', $query); // Split out words. $parts = explode(' ', $query); $skips = self::GetSkipWords(); $indexes = []; $primaries = []; $secondaries = []; foreach($parts as $word){ if(in_array($word, $skips)) continue; if(!$word) continue; $it = new DoubleMetaPhone($word); $indexes[] = $word; $primaries[] = $it->primary; $secondaries[] = $it->secondary; } // Remove duplicates $indexes = array_unique($indexes); $primaries = array_unique($primaries); $secondaries = array_unique($secondaries); // And add a where clause for each one. foreach($indexes as $word){ if($word) { // Required to skip spaces. $subwhere->addWhere('search_index_str LIKE %' . $word . '%'); } } foreach($primaries as $word){ if($word){ // Required to skip spaces. $subwhere->addWhere('search_index_pri LIKE %' . $word . '%'); } } foreach($secondaries as $word){ if($word){ // Required to skip spaces. $subwhere->addWhere('search_index_sec LIKE %' . $word . '%'); } } return $subwhere; }