Нужна очень головоломная сортировка для Views

Главные вкладки

Аватар пользователя direqtor direqtor 21 августа 2013 в 5:35

Итак. Есть сайт на Drupal 6. На сайте сделан поиск с использованием Views и exposed filters. Поиск ведется по нескольким текстовым полям CCK с оператором «Содержит». Все всех устраивало и даже отлично ищет, но на днях из высших сфер поступила задача отсортировать выдачу поиска. Высшие сферы бывает хотят странного, но с их точки зрения - это вроде как тривиально и во всех программах должно быть. Smile Суть в том, чтобы материалы, у которых введенное пользователем значение полностью совпадает с полем по которому ищут, выдавались выше, чем те материалы, в поле которых оно только содержится. Имитация релевантности. И совершенно ясно, что тут надо реализовать свой класс views_handler_sort.

При поиске по полю field_custom в материале mytype Views формирует приблизительно такой запрос:

SELECT
  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 ('%поисковый запрос%'))

Идея заключается в том, чтобы докинуть в запрос виртуальное поле с поиском по полному вхождению поискового запроса:

SELECT
  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

SELECT
  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 правильнее всего переопределять для этого?
Есть ли возможность избежать дублирования строк в случае поиска по многозначному полю или по нескольким таким полям одновременно?
Какой из вариантов проще реализовать?

Нужны идеи или советы коллективного разума с опытом разработки подобного функционала.

Комментарии

Аватар пользователя Chyvakoff Chyvakoff 21 августа 2013 в 9:32

"direqtor" wrote:
на днях из высших сфер поступила задача

Сочувствую. Щас дальше почитаю.
Я бы ещё так попробовал.
добавляешь в запрос искомую строку. То есть SELECT nid,title,created,cck_field,'содержимое поля' as zapros
и добавляешь if в котором сравниваешь cck_field и zapros. И по колонке, созданной ифом сортируешь.

Аватар пользователя direqtor direqtor 21 августа 2013 в 10:20

Да, такой вариант быстрее будет:

SELECT
  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

Но остальных вопросов не снимает.

Аватар пользователя webpavilion webpavilion 21 августа 2013 в 12:04

Не рассматриваете другие варианты кроме ковыряния views api?

У меня была подобная проблема с клиентским сайтом, после того как его владелец посетил курсы "SEO для начинающих" ему срочно потребовалась морфология - проблема решилась переносом поиска на Sphinx.

Сейчас я бы делал то же самое но на Apache Solr.