Я делаю простую поисковую систему, и я уже проиндексировал множество сайтов в базе данных MySQL. Теперь я хотел бы получить соответствующий список результатов по ключевым словам.
Сайты индексируются в моей базе данных со следующими столбцами: имя хоста (без протокола порт), заголовок, описание. (Нас не волнует путь)
Когда я набираю несколько ключевых слов на своей домашней странице поисковой системы, сначала начинается выборка 50 сайтов с использованием индексов FULLTEXT.
Теперь, поскольку использование алгоритма Левенштейна в MySQL очень медленное, я хотел бы отсортировать эти результаты с помощью функции Левенштейна PHP для каждого столбца, который я перечислил ранее.
Я хотел бы отсортировать их в следующем порядке (сначала самое важное): имя хоста, название, а затем описание.
Итак, у меня есть пять массивов:
Вот код:
$results = $req->fetchAll();
$search = strtolower($q);
$temp_arr = [];
$sorted_by_mysql = $sorted_by_hostname = $sorted_by_title = $sorted_by_description = [];
// We keep the original order in an array
for($i = 0; $i < count($results); $i++) $sorted_by_mysql[] = $i;
// Sort by hostname
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->hostname));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_hostname[] = $k;
// Sort by title
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->title));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_title[] = $k;
// Sort by description
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->description));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_description[] = $k;
Наконец, я хотел бы отсортировать результаты $, комбинируя (по приоритету) все эти разные массивы. Но я понятия не имею, как, так что вот где мне нужна помощь!
РЕДАКТИРОВАТЬ: Решение!
$data = $req->fetchAll();
$search = strtolower($q);
$temp = [];
foreach($data as $i => $row) {
$temp[] = [
'id' => $i,
'lev1' => levenshtein($search, strtolower($row->hostname)),
'lev2' => levenshtein($search, strtolower($row->title)),
'lev3' => levenshtein($search, strtolower($row->description))
];
}
$sorted = array_orderby($temp, 'lev1', SORT_ASC, 'lev2', SORT_ASC, 'lev3', SORT_ASC, 'id', SORT_ASC);
$results = [];
foreach($sorted as $row) {
$results[] = $data[$row['id']];
}
// Perfectly sorted !
Вот функция array_orderby:
// Credits : jimpoz at jimpoz dot com (PHP.net)
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
Смотрите ответ на этот ТАК вопрос, они имеют аналогичную потребность, но структурировали свои данные таким образом, чтобы облегчить ответ. Похоже, PHP поддерживает сортировка по нескольким атрибутам (в порядке убывания), если эти атрибуты встроены в сортируемый ассоциативный массив.
Чтобы применить этот подход к вашим данным, вы, вероятно, захотите реструктурировать свои результаты в один гигантский ассоциативный массив, где каждый элемент массива содержит значение для каждого «поля», которое вы хотите отсортировать. Имеет ли это смысл?
Удачи!
Других решений пока нет …