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

  • Автор темы Pimen
  • 60
  • Обновлено
  • 14, May 2024
  • #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
Код (разметка): Любая помощь, подсказки и предложения будут приняты с благодарностью.

Pimen


Рег
12 Jan, 2016

Тем
1

Постов
1

Баллов
11
  • 18, May 2024
  • #2
Вы можете немного взломать и заставить его работать без особых усилий.

В предложении 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): Вероятно, есть и другие способы сделать это.

Этот метод должен быть незначительным по сравнению с некоторыми другими способами, которые я могу придумать, чтобы сделать то же самое, например, объединения, хранимые процедуры или выполнение этого с двумя запросами в приложении.
 

sayber1


Рег
01 Dec, 2014

Тем
0

Постов
2

Баллов
2
  • 04, Jun 2024
  • #3
Это выглядит чертовски сложно, но вот что я делаю на сайте 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";
Код (разметка):
 

Mielna Luna


Рег
14 Jan, 2011

Тем
0

Постов
1

Баллов
1
Тем
49554
Комментарии
57426
Опыт
552966

Интересно