Перейти к содержанию
rider76

Улучшение поиска товаров

Рекомендуемые сообщения

Добрый день. Искал решение проблемы по реализации поиска на форуме и не только и не нашел. Необходимо организовать поиск по модели так, что бы запрос на поиск например номера 81.41685-0040, 81-41685-0040, A81416850040, 81 41685 0040 считался одним и тем же, то есть пробелы, точки, тире, другие знаки и т.д. опускались и выводилась позиция с моделью 81416850040. В том числе и наоборот. Существует модуль автоподстановки, типа как в google, снизу окна поиска появляются позиции, подходящие под запрос, но это не совсем то. Возможно его можно переработать под такие нужды, но у меня не получилось.

Позиции не должны снизу окна показываться, а должны появляться именно уже в модуле поиска в результатах поиска. Такой принцип организован в основном на сайтах автозапчастей, так как маски номеров у разных производителей различны. Да и я думаю это будет полезно для всех. Никто не знает как посетитель введет запрос поиска- товар20 или товар 20. Подсветка снизу не совсем удобна, многие даже не смотрят что появляется во время ввода, нажимают enter и смотрят результат.

Возможно даже можно сделать с помощью чекбоксов точный поиск по номеру ( например 123 и выводится именно 123) и поиск с начала номера (когда в результатах появляются позиции начинающиеся с 123) Прошу профессионалов не очень сильно ругаться, я правда пробовал переделать модуль автоподстановки, но мои знания PHP пока оставляют желать лучшего. Буду признателен за ответ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для наглядности приведу пример поиска с игнорированием символов.

Сайт всем известного интернет магазина запчастей www.exist.ru. Введите в окно поиска номер 50+10*26-0.052 (цилиндр сцепления рено). Все символы между цифрами игнорируются и в результатах появляется позиция с номером в таком виде 5010 260 052.Подскажите как это реализовать, очень нужно, и я думаю не мне одному. Существующий поиск практически бесполезен в таком виде как он есть сейчас.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

I have found advice on how to broaden the terms used for the OC site search (to search all categories by default instead of using a dropdown), which looks much nicer. I am not great working with code, so sorry for the stupid inquiry (if it is, in fact, stupid). I am trying to broaden search results for my customers to try to get close match, but not exact match searches.

Is there any way to have OC ignore certain characters when deriving search results? For example, many IT products have different variations of the same product number, sometimes using characters like /, -, etc, and sometimes not. I'm trying to modify the search so any special characters get stripped, and the search ignores any special characters in the product name, description, and product model. That way, if a user searches for, say, LC41BK, they will get back LC-41BK (the search ignores the special char), and vise versa (so if they search for 797-1, it will bring back 7971 as a match).

If anyone has had any luck with this, or could point me in the right direction, I would greatly appreciate it.

Прочесал зарубежный форум. Выше один из подобных моему вопрос. Даже странно, что ни на один подобный вопрос нет нигде ответа ответа. Откликнитесь кто знает PHP.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Унверсальное решение будет нагружать сервер

Лучше переписать контроллер по созданию товара, чтобы название всегда имело определённый вид (например только цифры)

А перед поиском уже убрать всякий мусор

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Унверсальное решение будет нагружать сервер

Лучше переписать контроллер по созданию товара, чтобы название всегда имело определённый вид (например только цифры)

А перед поиском уже убрать всякий мусор

Переписывать контроллер придется полностью или добавлять какие-то переменные? Здесь речь идет даже не о названии, а скорей всего о модели (артикуле). Нашел что то похожее в регулярных выражениях PHP в модификаторах:

/слово

#комментарий

ищу/x

будет искать 'словоищу'. То есть, здесь игнорируются пробелы и все, что следует за знаком диез.

Это я взял отсюда - http://phpforum.ru/index.php?showtopic=15291

Вот только как это применить я не знаю. Есть варианты как это сделать? Или я не туда копаю ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день. Искал решение проблемы по реализации поиска на форуме и не только и не нашел. Необходимо организовать поиск по модели так, что бы запрос на поиск например номера 81.41685-0040, 81-41685-0040, A81416850040, 81 41685 0040 считался одним и тем же, то есть пробелы, точки, тире, другие знаки и т.д. опускались и выводилась позиция с моделью 81416850040. В том числе и наоборот. Существует модуль автоподстановки, типа как в google, снизу окна поиска появляются позиции, подходящие под запрос, но это не совсем то. Возможно его можно переработать под такие нужды, но у меня не получилось.

Позиции не должны снизу окна показываться, а должны появляться именно уже в модуле поиска в результатах поиска. Такой принцип организован в основном на сайтах автозапчастей, так как маски номеров у разных производителей различны. Да и я думаю это будет полезно для всех. Никто не знает как посетитель введет запрос поиска- товар20 или товар 20. Подсветка снизу не совсем удобна, многие даже не смотрят что появляется во время ввода, нажимают enter и смотрят результат.

Возможно даже можно сделать с помощью чекбоксов точный поиск по номеру ( например 123 и выводится именно 123) и поиск с начала номера (когда в результатах появляются позиции начинающиеся с 123) Прошу профессионалов не очень сильно ругаться, я правда пробовал переделать модуль автоподстановки, но мои знания PHP пока оставляют желать лучшего. Буду признателен за ответ.

Данную проблему можно решить путем добавления тегов в товары и установки поиска и по модели и по названию

В файле catalog\view\theme\ваша_тема\template\product\ search.tpl

строку:

url = 'index.php?route=product/search';

заменить на:

url = 'index.php?route=product/search&model=1&description=1';

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Необходимо организовать поиск по модели так, что бы запрос на поиск например номера 81.41685-0040, 81-41685-0040, A81416850040, 81 41685 0040 считался одним и тем же, то есть пробелы, точки, тире, другие знаки и т.д. опускались и выводилась позиция с моделью 81416850040. В том числе и наоборот.

Попробуй перечитать постановку задачи.

Сначала пишеш много букв, перечисляеш что надо пропускать, а судя по приведённому примеру - поиск должен быть только по цифрам (коротко и ясно!). Решается такая задача с использованием простейшего регулярного выражения

preg_replace('/D/', '', $keyword)
Но мой модуль телепатии упорно не хочет работать, а модуль крипто-анализа не справился с фразой "В том числе и наоборот".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуй перечитать постановку задачи.

Сначала пишеш много букв, перечисляеш что надо пропускать, а судя по приведённому примеру - поиск должен быть только по цифрам (коротко и ясно!). Решается такая задача с использованием простейшего регулярного выражения

preg_replace('/D/', '', $keyword)
Но мой модуль телепатии упорно не хочет работать, а модуль крипто-анализа не справился с фразой "В том числе и наоборот".

Прошу прощения, какие файлы надо править? А вообще все верно, в этой задаче поиск идет только по цифрам. "В том чилсе и наоборот" можно опустить. Это уже было бы так сказать идеальное решение. Просто в этом случае артикул (модель) будет заполняться как цифр без пробелов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поиск только по цифрам в модели делается так:

В файле catalog/model/catalog/product.php

найди

$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
и замени на

$sql .= " OR p.model LIKE '%" . $this->db->escape(preg_replace('/\D/', '', $keyword)) . "%')";
Но в этом решении есть подводные камни... Например, если попытаться найти модель35 то реально будет поиск по вхождению числа 35 и результатов может быть неприлично много. Кроме этого кто-то из пользователей захочет поискать по фразе вообще не содержащей цифр и получит вообще все товары. Тут, по хорошему, напрашивается создание отдельной формы для поиска по артикулу.

Что можно попытаться сделать на базе того что есть и при этом получить более менее вменяемые результаты...

Проверять что-бы для поиска по модели было не менее 3 цифр и искать не вхождение, а товары у которых модель начинается с этих цифр.

Если цифр меньше 3 - искать по введённой фразе.

$number = preg_replace('/\D/', '', $keyword);
if (strlen($number) > 2) {
	$sql .= " OR p.model LIKE '" . $number . "%')";
} else {
	$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
}

Исправил ошибку в регулярке /D/ на /\D/

Изменено пользователем Yesvik
  • +1 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

preg_replace('/D/', '', $keyword)

Эта регулярка к числам отношения не имеет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поиск только по цифрам в модели делается так:

В файле catalog/model/catalog/product.php

найди

$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
и замени на

$sql .= " OR p.model LIKE '%" . $this->db->escape(preg_replace('/D/', '', $keyword)) . "%')";
Но в этом решении есть подводные камни... Например, если попытаться найти модель35 то реально будет поиск по вхождению числа 35 и результатов может быть неприлично много. Кроме этого кто-то из пользователей захочет поискать по фразе вообще не содержащей цифр и получит вообще все товары. Тут, по хорошему, напрашивается создание отдельной формы для поиска по артикулу.

Что можно попытаться сделать на базе того что есть и при этом получить более менее вменяемые результаты...

Проверять что-бы для поиска по модели было не менее 3 цифр и искать не вхождение, а товары у которых модель начинается с этих цифр.

Если цифр меньше 3 - искать по введённой фразе.

$number = preg_replace('/D/', '', $keyword);
if (strlen($number) > 2) {
	$sql .= " OR p.model LIKE '" . $number . "%')";
} else {
	$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
}
Я у себя чекбоксы поиск по модели и поиск по названию вообще убрал, а в функции прописал поиск по модели по умолчанию (хотя если ввести название он тоже его найдет что странно). Получается что сейчас в окно поиска я ввожу :

товар 11 - находит

11 - находит товар 11

товар11 - не находит

1 1 - не находит

пробел11 - выводит все позиции

При первом способе при вводе 21 (имеется ввиду товар 21) выводятся все позиции в которых встречаются цифра 2 и цифра 1.

При втором способе никаких отличий от стандартного поиска.

Хотя может я не то менял? (ту же строку что и при первом способе)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще я просмотрел много магазинов запчастей и выделил как минимум 2 способа как это делают.

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

При втором способе вводишь в окно запроса цифры со знаками пробелами и при нажатии на кнопку поиск цифры как бы съезжаются удаляя все лишнее между ними.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эта регулярка к числам отношения не имеет

Точно... обратный слеш потерял...

Должно быть /\D/

  • +1 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно... обратный слеш потерял...

Должно быть /\D/

Попробую, отпишусь о результатах. Есть еще одна тема для размышлений по поиску. Проблему высказали на зарубежном форуме. Решения тоже нет. Поиск по наименованию, например позиция Palm Treo Pro , поиск ее не найдет если в поиск ввести первое и последнее слово (Palm Pro). Я считаю это тоже большим упущением. Мне впринципе это особо ни к чему, но все же.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поиск только по цифрам в модели делается так:

В файле catalog/model/catalog/product.php

найди

$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
и замени на

$sql .= " OR p.model LIKE '%" . $this->db->escape(preg_replace('/\D/', '', $keyword)) . "%')";
Но в этом решении есть подводные камни... Например, если попытаться найти модель35 то реально будет поиск по вхождению числа 35 и результатов может быть неприлично много. Кроме этого кто-то из пользователей захочет поискать по фразе вообще не содержащей цифр и получит вообще все товары. Тут, по хорошему, напрашивается создание отдельной формы для поиска по артикулу.

Что можно попытаться сделать на базе того что есть и при этом получить более менее вменяемые результаты...

Проверять что-бы для поиска по модели было не менее 3 цифр и искать не вхождение, а товары у которых модель начинается с этих цифр.

Если цифр меньше 3 - искать по введённой фразе.

$number = preg_replace('/\D/', '', $keyword);
if (strlen($number) > 2) {
	$sql .= " OR p.model LIKE '" . $number . "%')";
} else {
	$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
}

Исправил ошибку в регулярке /D/ на /\D/

Огромное спасибо, все работает по обоим вариантам так как описано. Немного уточню- строка

$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";

Присутствует в двух местах в коде. Я брал второй вариант, так как он действительно более точный и удобный, я менял весь кусок кода в двух местах, этот

if (!$model) {
				$sql .= ")";
			} else {
				$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
			}
заменил на:

$number = preg_replace('/\D/', '', $keyword);
            if (strlen($number) > 2) {
                $sql .= " OR p.model LIKE '" . $number . "%')";
            } else {
                $sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
            }

При данном способе артикул (модель) в админке должен быть ряд цифр без пробелов, иначе не работает. Еще есть один нюанс при втором способе - если при запросе впереди номера окажется пробел, поиск выведет все позиции.

Еще раз огромное спасибо Yesvik.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Строка

$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
встречается дважды, я забыл об этом написать, и менять надо в обеих местах...

Но менять надо только эту строку, иначе поиск по модели будет всегда независимо от чекбокса.

Все позиции не должны выводиться... вот эта строка

$number = preg_replace('/\D/', '', $keyword);
удаляет всё кроме цифр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Строка

$sql .= " OR p.model LIKE '%" . $this->db->escape($keyword) . "%')";
встречается дважды, я забыл об этом написать, и менять надо в обеих местах...

Но менять надо только эту строку, иначе поиск по модели будет всегда независимо от чекбокса.

Все позиции не должны выводиться... вот эта строка

$number = preg_replace('/\D/', '', $keyword);
удаляет всё кроме цифр.
Получается я неправильно менял код?

Как я выше написал работает, между цифрами все удаляет, а впереди номера если вставить пробел то выводит все позиции, там же по условию поиск с начала номера, вот и получается если в начале номера пробел он и выводит все. А чекбоксы у меня постоянно включены оба и внешне на сайте вообще не отображаются, я менял строку в фале

\catalog\view\theme\ТЕМА\template\product\ search.tpl

эту

url = 'index.php?route=product/search
на эту

url = 'index.php?route=product/search&model=1&description=1';

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При вводе запроса, когда перед номером стоит пробел, относится только к пробелу, вставлять перед номером любые знаки можно, поиск найдет модель, а все позиции выводит только когда впереди стоит пробел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При вводе запроса, когда перед номером стоит пробел, относится только к пробелу, вставлять перед номером любые знаки можно, поиск найдет модель, а все позиции выводит только когда впереди стоит пробел.

Мне у себя лень проверять, но очень странно...

Вот эта функция

preg_replace('/\D/', '', $keyword)
должна удалять всё кроме цифр.

Попробуй строку

$number = preg_replace('/\D/', '', $keyword);
изменить так

$number = preg_replace('/\D|\s/', '', $keyword);
или так

$number = trim(preg_replace('/\D/', '', $keyword));
  • +1 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне у себя лень проверять, но очень странно...

Вот эта функция

preg_replace('/\D/', '', $keyword)
должна удалять всё кроме цифр.

Попробуй строку

$number = preg_replace('/\D/', '', $keyword);
изменить так

$number = preg_replace('/\D|\s/', '', $keyword);
или так

$number = trim(preg_replace('/\D/', '', $keyword));

Не работают такие вырианты, что-то здесь не так. Выводятся так же все позиции при пробеле в конце и между цифрами если поставить двойной пробел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне у себя лень проверять, но очень странно...

Вот эта функция

preg_replace('/\D/', '', $keyword)
должна удалять всё кроме цифр.

Попробуй строку

$number = preg_replace('/\D/', '', $keyword);
изменить так

$number = preg_replace('/\D|\s/', '', $keyword);
или так

$number = trim(preg_replace('/\D/', '', $keyword));
Есть еще какие варианты? Может изменить все это путем перечисления того что надо игнорировать? Как это делается? Просмотрел всю номенклатуру, оказывается буквы тоже нужны

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поиск с игнорированием знаков решил вот таким выражением:

$model = str_replace(array('_', '-', '—', '.', ',', ' ', '+', '/'), '', $keyword);

Здесь я просто перечислил что игнорировать, проблему с двойными пробелами и с пробелами в конце и в начале строки так и не решил. Функция trim почему-то не хочет работать или я ее неправильно применяю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Описывать что запрещено - неблагодарное занятие. Правильнее перечислять что разрешено.

Попробуй так

$number = preg_replace('/[^0-9]+/u', '', $keyword);
  • +1 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Описывать что запрещено - неблагодарное занятие. Правильнее перечислять что разрешено.

Попробуй так

$number = preg_replace('/[^0-9]+/u', '', $keyword);

Не работает такой вариант. Знаков на самом деле , которые надо запретить немного. А этот знак разве не исключение означает ^ ? Я уже всю голову сломал с этими регулярками. Везде все работает, а в этом скрипте почти ничего. Как заставить удалить пробел вначале и конце строки? Я trim уже куда и как только не вставлял здесь. вариантов применения его много, а вот в этом куске кода не получается.

Должно выглядеть примерно так

$str = "   Hello, world!   ";
$str = trim("   Hello, world!   ");

НО НЕ УДАЛЯЕТ ПРОБЕЛЫ И ВСЕ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А этот знак разве не исключение означает ^ ?

Всё верно, исключает.

Эта регулярка [^0-9]+ означает всё кроме цифр, а функция preg_replace('/[^0-9]+/u', '', $keyword) по русски звучит примерно так: найти в $keyword всё кроме цифр и удалить (заменить на '' ). Модификатор u предписывает рассматривать шаблон в кодировке UTF-8. Почему не работает - не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.