Пример #1
0
	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);
	}
Пример #2
0
	/**
	 * 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;
	}