Упорядочите поиск по полным совпадениям, а затем по частичным совпадениям.

Pimen

Пользователь
Регистрация
12.01.16
Сообщения
1
Реакции
0
Баллы
1
Привет,

Я работаю над довольно сложным поиском на собственном сайте WordPress.

У нас есть индивидуальный поиск с различными фильтрами.
Упорядочите поиск по полным совпадениям, а затем по частичным совпадениям.
Если мы ищем что-то вроде «честер», мы получаем все результаты для Честера, но они также включают Манчестер и Чичестер. Мы хотим упорядочить их так, чтобы сначала отображались полные совпадения, а затем частичные.

Наш текущий SQL
Код:
SELECT DISTINCT wp_posts.ID , wp_posts.post_title , wp_posts.post_name , wp_posts.post_content , meta1.meta_value as keywords
FROM wp_posts
INNER JOIN wp_postmeta as meta1 ON meta1.post_id = wp_posts.ID AND meta1.meta_key = 'location_keywords'
INNER JOIN wp_postmeta as meta5 ON meta5.post_id = wp_posts.ID AND meta5.meta_key = 'parent_id'
INNER JOIN wp_posts as wp2 ON wp2.ID=meta5.meta_value AND wp2.post_type='ciet_company' AND wp2.post_status='publish'
WHERE wp_posts.post_status='publish' AND
meta1.meta_value LIKE '%chester%'
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_title
ASC LIMIT 20
Код (разметка): Любая помощь, подсказки и предложения будут приняты с благодарностью.
 

sayber1

Пользователь
Регистрация
01.12.14
Сообщения
2
Реакции
0
Баллы
1
Вы можете немного взломать и заставить его работать без особых усилий. В предложении SELECT вы по сути хотите выполнить тот же поиск, что и «chester%», и назначить им более высокий приоритет.

Кроме того, DISTINCT wp_posts.ID является избыточным, поскольку вы группируете по одному и тому же столбцу.

Попробуй это:

Код:
SELECT wp_posts.ID, wp_posts.post_title, wp_posts.post_name, wp_posts.post_content, meta1.meta_value AS keywords,
IF ( wp_posts.post_title LIKE 'chester%', 1, 0
) AS sort_priority
FROM wp_posts
INNER JOIN wp_postmeta AS meta1 ON meta1.post_id = wp_posts.ID
AND meta1.meta_key = 'location_keywords'
INNER JOIN wp_postmeta AS meta5 ON meta5.post_id = wp_posts.ID
AND meta5.meta_key = 'parent_id'
INNER JOIN wp_posts AS wp2 ON wp2.ID = meta5.meta_value
AND wp2.post_type = 'ciet_company'
AND wp2.post_status = 'publish'
WHERE wp_posts.post_status = 'publish'
AND meta1.meta_value LIKE '%chester%'
GROUP BY wp_posts.ID
ORDER BY sort_priority DESC, wp_posts.post_title ASC
LIMIT 20
Код (SQL): Вероятно, есть и другие способы сделать это. Этот метод должен быть незначительным по сравнению с некоторыми другими способами, которые я могу придумать, чтобы сделать то же самое, например, объединения, хранимые процедуры или выполнение этого с двумя запросами в приложении.
 

Mielna Luna

Пользователь
Регистрация
14.01.11
Сообщения
1
Реакции
0
Баллы
1
Это выглядит чертовски сложно, но вот что я делаю на сайте cakePHP, который запускаю.

сценарий
=====
Кто-то зарегистрировался на мероприятие, и мы хотим знать, есть ли он уже в базе данных.
Сопоставление по названию компании — это хорошо, фамилия — полезно, сопоставление по имени — нет, сопоставление по электронной почте — лучше всего, сопоставление по мобильному телефону — лучше всего, сопоставление по рабочему телефону — не так надежно

Итак, мы прорабатываем возможные данные, которые мог предоставить пользователь, и создаем массив с именем $relevance.



Код:
$str = 'chester';
$relevance = array();
$relevance[] = "CASE WHEN `wp_posts`.`post_title` = '{$str}' THEN 4 ELSE 0 END";
$relevance[] = "CASE WHEN `wp_posts`.`post_title` like '%{$str}%' THEN 2 ELSE 0 END";
$relevance_string = '('.implode(' + ', $relevance) .') as `relevance`';
$sql = "SELECT DISTINCT wp_posts.ID , wp_posts.post_title , wp_posts.post_name , wp_posts.post_content , meta1.meta_value as keywords, {$relevance_string}
FROM wp_posts
INNER JOIN wp_postmeta as meta1 ON meta1.post_id = wp_posts.ID AND meta1.meta_key = 'location_keywords'
INNER JOIN wp_postmeta as meta5 ON meta5.post_id = wp_posts.ID AND meta5.meta_key = 'parent_id'
INNER JOIN wp_posts as wp2 ON wp2.ID=meta5.meta_value AND wp2.post_type='ciet_company' AND wp2.post_status='publish'
WHERE wp_posts.post_status='publish' AND
meta1.meta_value LIKE '%chester%'
GROUP BY wp_posts.ID
ORDER BY `relevance` DESC
ASC LIMIT 20";


Код (разметка): у нас есть большой массив, дающий очки. Имя участника может использоваться более одного для получения разного количества баллов в зависимости от точного или частичного совпадения.

затем в свой список полей, которые мне нужны для запроса, я добавляю релевантность и использую это для упорядочивания результатов
$fields[] = '(' . implode(' + ', $relevance) . ') as `relevance`'; $order = array('relevance desc');
Код (разметка): Чтобы использовать эту концепцию в своем запросе, вам нужно сделать что-то вроде этого:

$relevance[] = "CASE WHEN `Membership`.`name` = '{$this->request->data['Registration']['tradingname']}' THEN 4 ELSE 0 END";
Код (разметка):
 
Сверху Снизу