Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

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


rider76

Recommended Posts

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

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

Вы пишите " звучит примерно так: найти в $keyword всё кроме цифр ". Но в $keyword и так нет пробелов в начале и в конце, я думаю в этом проблема с trim. Он удаляет там где они есть, а они есть в только что написанном тексте пользователем, но не в $keyword. Получается такая штука; строка $str запрашивает в $keyword, а строка $str=trim() удаляет пробелы в строке $str , в которой к этому моменту уже просто ничего нет. Надо попытаться как-то написать код так, что-бы исправлялось все еще до SQL запроса. Посетитель набрал номер артикула в поиск, и при нажатии кнопки сначала исправлялась его запись, а потом уже шел запрос в $keyword.

Надіслати
Поділитися на інших сайтах


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

А попробуй посмотреть что такое $keyword

Это как раз и есть только что написанный пользователем текст...

Надіслати
Поділитися на інших сайтах

советую почитать на досуге всем желающим улучшить поиск: opennet :: Полнотекстовый поиск в MySQL на PHP (mysql search php web)

Это как раз и есть только что написанный пользователем текст...

полученный из $_GET, поэтому там вместо пробела %20
Надіслати
Поділитися на інших сайтах

советую почитать на досуге всем желающим улучшить поиск: opennet :: Полнотекстовый поиск в MySQL на PHP (mysql search php web)

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

Надіслати
Поділитися на інших сайтах


если не получается скальпелем - берите топор.

режьте их на JS до отправки формы.

в инете масса примеров "trim`a" на JS.

Надіслати
Поділитися на інших сайтах

Да, долго бы ещё гадали...

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

Кроме поиска в названиях, описании и модели - постоянно идёт поиск по тэгам и реализован он через ...

Всё начинается с модели товара. Когда добавляется или редактируется товар - вот так обрабатываются теги:

foreach ($data['product_tags'] as $language_id => $value) {
	$tags = explode(',', $value);
	foreach ($tags as $tag) {
		$this->db->query("INSERT INTO " . DB_PREFIX . "product_tags (product_id, language_id, tag) VALUES ('" . (int)$product_id . "', '" . (int)$language_id . "', '" . $this->db->escape(trim($tag)) . "')");
	}
}
Никакого контроля на наличие тегов и в результате, для товаров без тегов, получаем записи с пустыми значениями.

Дальше за дело принимается поиск по тегам...

$keywords = explode(" ", $tag);

foreach ($keywords as $keyword) {
	$sql .= " OR pt.tag = '" . $this->db->escape($keyword) . "'";
}
Вот из-за этой хрени - пробел в начале, пробел в конце или двойной пробел в середине приведут к поиску товаров с пустыми тегами, а их у нас предостаточно из-за подарка в модели...

Так что регулярка тут не при чем и трим работает нормально.

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

Надіслати
Поділитися на інших сайтах

В файле admin/model/catalog/product.php ищем строку

$tags = explode(',', $value);
эта строка встречается 2 раза и после каждой найденной строки добавляем строку

$tags = array_filter(array_map('trim', $tags), 'strlen');

В файле catalog/model/catalog/product.php ищем строку

$keywords = explode(" ", $tag);
эта строка встречается 2 раза и после каждой найденной строки добавляем строку

$keywords = array_filter(array_map('trim', $keywords), 'strlen');

Теперь надо вычистить из таблицы oc_product_tags записи с пустыми тегами.

Сделать это можно разными способами, например вот таким SQL-запросом:

DELETE FROM oc_product_tags WHERE tag = '';
Только не забудь исправить префикс таблицы oc_ на свой.

После этого строка

$number = preg_replace('/\D+/', '', $keyword);
или

$number = preg_replace('/[^0-9]+/', '', $keyword);
будет нормально отрабатывать и trim() не понадобится.

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

  • +1 3
Надіслати
Поділитися на інших сайтах

  • 3 months later...

В файле admin/model/catalog/product.php ищем строку

$tags = explode(',', $value);
эта строка встречается 2 раза и после каждой найденной строки добавляем строку

$tags = array_filter(array_map('trim', $tags), 'strlen');

В файле catalog/model/catalog/product.php ищем строку

$keywords = explode(" ", $tag);
эта строка встречается 2 раза и после каждой найденной строки добавляем строку

$keywords = array_filter(array_map('trim', $keywords), 'strlen');

Теперь надо вычистить из таблицы oc_product_tags записи с пустыми тегами.

Сделать это можно разными способами, например вот таким SQL-запросом:

DELETE FROM oc_product_tags WHERE tag = '';
Только не забудь исправить префикс таблицы oc_ на свой.
спасибо помогает избавиться от всех результатов в обычном поиске за исключением если искать просто пробел
Надіслати
Поділитися на інших сайтах

  • 3 months later...

В файле admin/model/catalog/product.php ищем строку

$tags = explode(',', $value);
эта строка встречается 2 раза и после каждой найденной строки добавляем строку

$tags = array_filter(array_map('trim', $tags), 'strlen');

В файле catalog/model/catalog/product.php ищем строку

$keywords = explode(" ", $tag);
эта строка встречается 2 раза и после каждой найденной строки добавляем строку

$keywords = array_filter(array_map('trim', $keywords), 'strlen');

Теперь надо вычистить из таблицы oc_product_tags записи с пустыми тегами.

Сделать это можно разными способами, например вот таким SQL-запросом:

DELETE FROM oc_product_tags WHERE tag = '';
Только не забудь исправить префикс таблицы oc_ на свой.

После этого строка

$number = preg_replace('/D+/', '', $keyword);
или

$number = preg_replace('/[^0-9]+/', '', $keyword);
будет нормально отрабатывать и trim() не понадобится.

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

Добрый день!!! Помогите проделать ту же операцию что и с артикулом

$number = preg_replace('/D+/', '', $keyword);
, только применить к тегам товаров. Что-то не получается. Заранее благодарю.
Надіслати
Поділитися на інших сайтах


Строку

$sql .= " OR pt.tag = '" . $this->db->escape($keyword) . "'";

заменил на

$sql .= " OR pt.tag = '" . $this->db->escape(preg_replace('/D/', '', $keyword)) . "'";

все работает, но почему то не удаляются пробелы в центре.

Надіслати
Поділитися на інших сайтах


  • 3 months later...

Тоже столкнулся с проблемой поиска на OpenCart 1.5.1.3

у меня предвидется много товаров с похожими названиями, примерно может быть 35 000-45 000 товаров. вчера залил первые 150 товаров и поиграся споиском и понял что ничего клиент не найдет, так как поиск или ничего не находит и или вываливает почти все товары, причем в нерелевантно последовательности, т.е. искомый товар с точным вхождением может быть (и чаще так и есть) не на 1 месте на 100 каком-то.

Наилучшие результаты если искать ставить галочку "искать в описании" и делать поиск по какому то парметру из описания товара.

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

У меня названия товаров примерно такого принципа:

Шариковая ручка Parker Gold 100

Шариковая ручка Parker Gold 200

Шариковая ручка Parker Gold 300

Шариковая ручка Pelikan Blu 100

Шариковая ручка Pelikan Blu 200

Шариковая ручка Pelikan Blu 300

Шариковая ручка Pelikan Blu 400

Шариковая ручка Master Platinum 100

Шариковая ручка Master Platinum 200

Шариковая ручка Master Platinum 300

Т.е. "Шариковая ручка" встречается почти во всех наименованиях товара, это само повторяющаяся фраза, также имя бренда : Parker, Pelikan, Master тоже очень асто встречается и может быть более 1000 товаров с таким вхождением.

Например если я ввожу запрос: Шариковая ручка Parker Gold 100 то хотел бы чтобы результат поиска в данном случае был с точным вхождением, т.е. Шариковая ручка Parker Gold 100 но поиск на сайте выдаст все результаы где есть хоть какое то слово из запроса, а так как названия товара на 5-70% похоже, то в запросе вывалится тысячи товара..... т.е. почти все

подскажите как боле точно подкоректировать работу поиска, чтобы он более точно и релевантно работал.

Может я что-то не так заполнил в формах товара что портит все результаты?

тут в топике написано что теги как-то участвуют в алгоритме поиска, спрашивал у других, гвоорят - что нет, не участвуют.

у меня они прописаны и равны названию товара.

Нуждаюсь в консультации и помощи в том числе можно и за вознаграждение (небольшое но все же)

если что ася для связи 203-410-102

Змінено користувачем siniy
Надіслати
Поділитися на інших сайтах


поиск фразы полностью

catalog/model/catalog/product.php, 53, 417

куски

           	 if (!empty($data['filter_name'])) {

                    $implode = array();
                    
                    $words = explode(' ', $data['filter_name']);
                    
                    foreach ($words as $word) {
                        if (!empty($data['filter_description'])) {
                            $implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
                        } else {
                            $implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
                        }                
                    }
                    
                    if ($implode) {
                        $sql .= " " . implode(" OR ", $implode) . "";
                    }
                }

заменить на

           	 if (!empty($data['filter_name'])) {
               	 $sql .= " LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "%'";
			    }
Надіслати
Поділитися на інших сайтах

не понял какие имено куски кода заменить нужно.

В первом окошке огромный кусок кода а в нижнем окне мало кода, нужно весь большой кусок заменить на этот один маленький или как?

Еще обнаружил такую проблемму при работе поиска:

Если я в слайдере производителей выберу palm и потом в этом разделе сайта введу в поиск m100 то нахожу один нужный товар, т.е. так как нужно.

Но если я используя расширеный поиск, выбираю фильтр искать в категори Palm и делаю тот же запрос m100 то почему-то при таком подхоже вываливаются все товары (ну или по карйней мере не 1 результат а почти 200)

Почему так происходит?

Надіслати
Поділитися на інших сайтах


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

пример названия товаров в базе магазина, сейчас так названы:

Аккумулятор для Palm M515 850 mAh

Аккумулятор для Palm M500 850 mAh

Аккумулятор для Palm M505 850 mAh

Аккумулятор для Palm M515 1350 mAh

Аккумулятор для Palm M500 1350 mAh

Аккумулятор для Palm M505 1350 mAh

Аккумулятор для Palm M550 850 mAh

Аккумулятор для Palm TUNGSTEN T1 850 mAh

Аккумулятор для HTC HD 850 mAh

Аккумулятор для HTC HD 2 850 mAh

Аккумулятор для HTC Ace 850 mAh

Аккумулятор для HTC EVO4 1350 mAh

Аккумулятор для HTC Hero 1350 mAh

Аккумулятор для HTC Wildfire 1350 mAh

Аккумулятор для HTC Touch2 850 mAh

Аккумулятор для HTC Legend 850 mAh

Аккумулятор для Nokia 6300 850 mAh

Аккумулятор для Nokia N73 850 mAh

Аккумулятор для Nokia N93 850 mAh

Скорей всего "Аккумулятор для" заменю на Аккумуляторная батарея

Еще в магазине будут товары с названием вида:

Зарядное устройство для аккумуляторной батареи BL-6C

Защитная пленка Diamond для HTC HD2

Посетитель может ввести в запросе : Аккумулятор для HTC Touch2 или Аккумулятор для HTC Touch 2 850 mAh или Батарея для HTC Touch2 или Аккумуляторная батарея для HTC Touch2 или HTC Touch2 или HTC Touch 2

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

Но при этом чтобы так же в магазине также легко и нормально находились товары типа:

Защитная пленка Diamond для HTC HD2

Зарядное устройство для аккумуляторной батареи BL-6C

Зарядное устройство для HTC HD2

Зарядное устройство для HTC HD 2

Автомобильное зарядное устройство для HTC HD 2

Автомобильное зарядное устройство для HTC HD2

Зарядное устройство USB для HD2

Зарядное устройство USB для HD 2

Powr Bank

Внешний аккумулятор

Внешняя батарея

Powr Doze

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

Надіслати
Поділитися на інших сайтах


  • 1 month later...
  • 2 months later...

поиск фразы полностью

catalog/model/catalog/product.php, 53, 417

куски

		   	 if (!empty($data['filter_name'])) {

					$implode = array();
					
					$words = explode(' ', $data['filter_name']);
					
					foreach ($words as $word) {
						if (!empty($data['filter_description'])) {
							$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
						} else {
							$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
						}				
					}
					
					if ($implode) {
						$sql .= " " . implode(" OR ", $implode) . "";
					}
				}

заменить на

		   	 if (!empty($data['filter_name'])) {
			   	 $sql .= " LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "%'";
				}

А как еще к этому всему привязать чтобы искал по product_id?

Возможно?

Заранее благодарен!!!!

Надіслати
Поділитися на інших сайтах


  • 2 years later...

Версия ocStore Версия 1.5.5.1.2

Не нашел ни одной строки из приведенных в теме.

Причем искал не только в указанных файлах, но и в других, например, \catalog\controller\product\search.php

 

Короче, так и не нашел, где в моей версии можно исправить поиск на сайте.

Проблема заключается в поиске по цифрам!

Он не ищет товары по цифровой части модели.

То есть, если забить модель hr2450 - он выдаст Перфоратор SDS Plus и это будет правильно.

Если вставить пробел в строке поиска: hr 2450 - не найдет вообще ничего.

Если не указывать буквы, а ввести просто 2450 - найдет Бур SDS Plus для этого перфоратора.

 

То есть, поиск в базе такой, что лучше бы его вообще не было!

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

 

Что самое интересное, поиск по цифрам, когда их 5 выдает поиск по product_id! То есть, 5-значные цифровые запросы выдают товар с соответствующим ID.

 

Сайт: aniteks.ru

Надіслати
Поділитися на інших сайтах


У меня тоже проблема с поиском.

 

Приведу пример:

 

Есть товар с названием: "Опока - Е 91" - http://slonmaster.ru/index.php?route=product/product&path=70_168&product_id=1911
 
Если ввести точное название, то все срабатывает как надо.
 
Но если в поисковой форме задать такой запрос: Опока - Е91 , то он уже не находит этот товар.
 
Т.е. просто убрал пробел между Е и 91 и уже поиск не срабатывает. (Е - на кириллице)
 
 
Подскажите, пожалуйста как исправить это, уже все обрыл ничего не помогает.
Надіслати
Поділитися на інших сайтах


  • 1 month later...

Исправить? Это когда что-то сломалось

А то что вы описали правильное поведение.

Это не правильное поведение - это недопоиск.

Представьте, если бы в яндексе надо было соблюсти все пробелы и знаки препинания для поиска!

Например, вам нужно найти как правильно пишется какое-либо слово, или словосочетание и, пока вы не введете его правильно, яндекс вам не выдаст вообще никакого ответа!

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

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

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

Если все подстроки имеют вхождение в строку - этот ответ выдается первым, далее - по убывающей.

Надіслати
Поділитися на інших сайтах


1. Это не Яндекс.

2. Используйте поиск с морфологией. (ищите в модулях)

3. Не вопрос - разбивайте search на фразы и ищите (смотрите как делается поиск по описанию)

4. Вы еще о релевантности запроса  поговорите.

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.