Итак. Есть сайт на Drupal 6. На сайте сделан поиск с использованием Views и exposed filters. Поиск ведется по нескольким текстовым полям CCK с оператором «Содержит». Все всех устраивало и даже отлично ищет, но на днях из высших сфер поступила задача отсортировать выдачу поиска. Высшие сферы бывает хотят странного, но с их точки зрения - это вроде как тривиально и во всех программах должно быть. Суть в том, чтобы материалы, у которых введенное пользователем значение полностью совпадает с полем по которому ищут, выдавались выше, чем те материалы, в поле которых оно только содержится. Имитация релевантности. И совершенно ясно, что тут надо реализовать свой класс views_handler_sort.
При поиске по полю field_custom в материале mytype Views формирует приблизительно такой запрос:
node.title AS node_title,
node.nid AS nid,
node_data_field_custom.field_custom_value AS node_data_field_custom_field_custom_value,
FROM node node
LEFT JOIN content_type_mytype node_data_field_custom
ON node.vid = node_data_field_custom.vid
WHERE
(node.type IN ('mytype')) AND
(node.status = 1) AND
((node_data_field_custom.field_custom_value) LIKE ('%поисковый запрос%'))
Идея заключается в том, чтобы докинуть в запрос виртуальное поле с поиском по полному вхождению поискового запроса:
node.title AS node_title,
node.nid AS nid,
node_data_field_custom.field_custom_value AS node_data_field_custom_field_custom_value,
((node_data_field_custom.field_custom_value) LIKE ('поисковый запрос')) AS node_data_field_custom_field_custom_sort
FROM node node
LEFT JOIN content_type_mytype node_data_field_custom
ON node.vid = node_data_field_custom.vid
WHERE
(node.type IN ('mytype')) AND
(node.status = 1) AND
((node_data_field_custom.field_custom_value) LIKE ('%поисковый запрос%'))
ORDER BY
node_data_field_custom_field_custom_sort DESC
Можно попробовать по другому и добавить сортировку по длине поля field_custom
node.title AS node_title,
node.nid AS nid,
node_data_field_custom.field_custom_value AS node_data_field_custom_field_custom_value,
LENGTH(node_data_field_custom.field_custom_value) AS node_data_field_custom_field_custom_sort
FROM node node
LEFT JOIN content_type_mytype node_data_field_custom
ON node.vid = node_data_field_custom.vid
WHERE
(node.type IN ('mytype')) AND
(node.status = 1) AND
((node_data_field_custom.field_custom_value) LIKE ('%поисковый запрос%'))
ORDER BY
node_data_field_custom_field_custom_sort ASC
Обе идеи рабочие, но пока не знаю, как к этому подступиться, хотя опыт создания views_handler имеется.
Как зацепить handler за произвольное поле CCK произвольного типа нод и при этом не плодить их для всех полей?
Как выдрать поисковый запрос, если он не пуст?
Какие методы класса views_handler_sort правильнее всего переопределять для этого?
Есть ли возможность избежать дублирования строк в случае поиска по многозначному полю или по нескольким таким полям одновременно?
Какой из вариантов проще реализовать?
Нужны идеи или советы коллективного разума с опытом разработки подобного функционала.
Комментарии
Сочувствую. Щас дальше почитаю.
Я бы ещё так попробовал.
добавляешь в запрос искомую строку. То есть SELECT nid,title,created,cck_field,'содержимое поля' as zapros
и добавляешь if в котором сравниваешь cck_field и zapros. И по колонке, созданной ифом сортируешь.
Да, такой вариант быстрее будет:
node.title AS node_title,
node.nid AS nid,
node_data_field_custom.field_custom_value AS node_data_field_custom_field_custom_value,
(node_data_field_custom.field_custom_value = 'поисковый запрос') AS node_data_field_custom_field_custom_sort
FROM node node
LEFT JOIN content_type_mytype node_data_field_custom
ON node.vid = node_data_field_custom.vid
WHERE
(node.TYPE IN ('mytype')) AND
(node.STATUS = 1) AND
((node_data_field_custom.field_custom_value) LIKE ('%поисковый запрос%'))
ORDER BY
node_data_field_custom_field_custom_sort DESC
Но остальных вопросов не снимает.
Не рассматриваете другие варианты кроме ковыряния views api?
У меня была подобная проблема с клиентским сайтом, после того как его владелец посетил курсы "SEO для начинающих" ему срочно потребовалась морфология - проблема решилась переносом поиска на Sphinx.
Сейчас я бы делал то же самое но на Apache Solr.
Переделывать уже рабочий сайт очень не хочется.