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

Робимо ультимативний пошук для Opencart


ozzzi

1 340 переглядів

Думаю, всім зрозуміло, що коли асортимент магазину сягає десятків тисяч і більше, важливо мати зручний пошук на сайті. Стандартний LIKE-подібний пошук на великих обсягах не справляється ні зі швидкістю, ні зі зручністю відповіді. Я розповім, як зробити пошуковий механізм на основі систем, створених спеціально для пошуку.

 

Почну відразу з можливостей пошуку.

 

1. Пошук з урахуванням помилок

чихол -> чохол

 

Пошук артикулів у різних варіаціях:

SKU.1234 -> SKU-1234 -> SKU1234

 

2. Неправильна розкладка клавіатури:

xj[jk -> чохол

 

3. Пошук з урахуванням морфології мови: рід, число, відмінок:

сумка ноутбук -> сумки для ноутбуків

 

4. Семантичний пошук.

мікрохвильовка Samsung -> мікрохвильова піч Samsung

браслет мед макс -> браслет Mad Max 

 

До цього були показані приклади лексичного пошуку, тобто пошуку за конкретними символами. Семантичний (векторний) пошук шукає за смисловою схожістю. Даний підхід пов'язаний з великими мовними моделями. Тренуючись на купі інформації, LLM навчилися класифікувати поняття за тисячами факторів. Коли ми індексуємо наші товари, ми не зберігаємо їх у вигляді ключових слів, ми створюємо векторне (математичне) представлення слів, фраз. Сам вектор являє собою масив float значень. Якими саме будуть значення і їх розмірність безпосередньо залежить від моделі. Пошуковий запит також перетворюється на вектор і за допомогою математичних виразів ми перевіряємо близькість наших векторів, тобто наскільки семантично близькі поняття.

vektor.thumb.png.7af9a5cc6276e73d6cd50ff9a69ebbff.png

 

Для використання семантичного пошуку вам не потрібно завантажувати мовні моделі на десятки гігабайт і мати топову відеокарту, все працює на звичайному VPS.

 

Які функції реалізовані:

feature.thumb.png.af7843a22cc9701b19a5c3181601cbf7.png

 

 

  • Спливаюче вікно з автодоповненням
  • Пошукові підказки:
чохол:
чохол для телефону
чохол для ноутбука 

 

  • категорії із зазначенням кількості знайдених товарів

Тут відображаються не категорії, які збіглися із запитом пошуку, а категорії товарів, які відповідають умовам пошуку.

 

  • товари
  • Ви мали на увазі

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


З чого складається дане рішення:

  1. Пошуковий движок на вашому хостингу: Opensearch (форк ElasticSearch), Typesense або Meilisearch.
  2. API додаток на піддомені на основі Laravel.
  3. Embedding API
  4. HTTP-клієнт для Opencart з модулем пошуку.

 

Наведені вище можливості пошуку вказані для Opensearch. Далі також буде описуватися саме цей движок. Готові приклади для інших движків ви зможете знайти в репозиторії проекту.

 

Порівняння можливостей движків:

OpenSearch

  • Простота встановлення: ❌
  • Пошук з помилками: ✅
  • Морфологія: ✅
  • Виправлення розкладки клавіатури: ✅
  • Семантичний пошук: ✅

 

Typesense

  • Простота встановлення: ✅
  • Пошук з помилками: ✅
  • Морфологія: ❌
  • Виправлення розкладки клавіатури: ❌
  • Семантичний пошук: ✅

 

Meilisearch

  • Простота встановлення: ✅
  • Пошук з помилками: ✅
  • Морфологія: ❌
  • Виправлення розкладки клавіатури: ❌
  • Семантичний пошук: ❌

          

Чому окреме API? Я робив універсальне рішення для різних движків, а зробити таке в рамках опенкарта - нагородити купу "лапшекода"" без можливості виконання cli-скриптів, черг та інших принадностей цивілізації. У будь-якому випадку, установка API буде не складнішою за установку Opencart, знати Laravel зовсім не обов'язково.


Embedding API використовується тільки в Opensearch і тільки для семантичного пошуку. Це однофайлове API на основі FastAPI і Python, яке приймає рядок і повертає його векторне представлення. Запускається парою команд, ніяких знань Python від вас не потрібно.

 

Встановлення 

Для тих, хто не проти спробувати Docker, в репозиторії знаходиться готова конфігурація для запуску всієї інфраструктури однією командою.

 

1. Пошуковий движок.
Вибираєте пошуковий движок, який вам сподобався, і на офіційному сайті або в ChatGPT отримуєте відповідь про встановлення під вашу платформу. Від себе зазначу, що найпростіші в установці Typesense і Meilisearch. 

 

Для Opensearch необхідно встановити плагін для векторного пошуку:

/usr/share/opensearch/bin/opensearch-plugin install opensearch-knn

 

А також морфологію для української та російської мов:

/usr/share/opensearch/config/hunspell — тут створюємо папки: ru_RU, uk_UA, в яких будуть лежати файли *.dic, *.aff. Самі файли завантажуєте звідси:

https://raw.githubusercontent.com/LibreOffice/dictionaries/master/ru_RU/ru_RU.dic
https://raw.githubusercontent.com/LibreOffice/dictionaries/master/ru_RU/ru_RU.aff
https://raw.githubusercontent.com/LibreOffice/dictionaries/master/uk_UA/uk_UA.dic
https://raw.githubusercontent.com/LibreOffice/dictionaries/master/uk_UA/uk_UA.aff

 

Щодо семантичного пошуку. У кожному з движків можна використовувати OpenAI embedding (перетворювач рядків у вектори), але ви повинні розуміти, що він платний, тому я його не реалізовував. 

 

Якщо хочете використовувати тільки безкоштовні рішення:

  • OpenSearch - потрібен окремий Embedding API з безкоштовною моделлю. 
  • Typsense - є вбудований механізм embedding-а і невеликий список доступних моделей
  • Meilisearch - вбудованих механізмів embedding-а не знайшов, а окремий API для цього просто не став робити. Якщо вже заморочуватися, то краще отримати всі можливості Opensearch.

 

2. Embedding API
Повторю, що цей крок потрібен тільки для Opensearch при використанні семантичного пошуку.

Вибираємо директорію для проекту і копіюємо туди файли: 

docker/embedder/app/main.py - сам файл додатка
docker/embedder/requirements.txt - залежності, щось на зразок composer.json

 

Створюємо також .env файл з параметрами:

API_TOKEN=дивіться наступний пункт
SEARCH_EMBEDDING_MODEL=дивіться наступний пункт

 

Встановлюємо залежності (на сервері повинен бути Python)

pip install --no-cache-dir -r requirements.txt

 

Запускаємо сервер

uvicorn main:app --host 0.0.0.0 --port 8000

 

При першому запуску після установки знадобиться деякий час на ініціалізацію.

Щоб все це працювало після збоїв і перезапусків системи, створіть systemd unit (ChatGPT легко напише вам команди і конфігурацію)

 

3. Пошукове API

Копіюємо файли з github репозиторію в поточну директорію:

git clone https://github.com/ozzzi/api-opencart.git .

 

Створюємо файл середовища .env

cp .env.example .env

Заповнюємо його:

APP_NAME=API
APP_ENV=production
APP_DEBUG=false
APP_URL=http://ваш_урл 

 

налаштовуємо підключення до бази опенкарт

DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

 

доступ до API

API_TOKEN - токен аутентифікації для API
API_IP_ADDRESS - IP-адреса, з якої дозволені звернення

 

налаштування пошуку

SEARCH_API_KEY - токен доступу до opensearch, який вказали під час встановлення
SEARCH_USER - користувач opensearch
SEARCH_HOST
SEARCH_PORT
SEARCH_SSL - true/false

 

Модель для перетворення текстових даних у вектори

SEARCH_EMBEDDING_MODEL=sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2

 

для Typsense є список доступних моделей: https://huggingface.co/typesense/models-moved/tree/main. Можна вибрати, наприклад, ts/multilingual-e5-large, але зверніть увагу на розмір моделі, він може бути як кілька сотень мегабайт, так і кілька гігабайт і буде завантажений автоматично на ваш диск при першому використанні.

 

EMBEDDED_URL - адреса Embedding API, за замовчуванням адреса http://localhost:8000/vectorize

 

SEARCH_DISTANCE_THRESHOLD - порогова оцінка документа, якщо у документа вона буде нижчою, то він не потрапить у видачу. Даний параметр пов'язаний із семантичним пошуком. Коли ми порівнюємо вектори, ми обчислюємо відстань або кут між ними. У нашому випадку, чим ближче оцінка до 1, тим семантично наші вектори близькі. Якщо ми не будемо обмежувати допустиму оцінку документа, ми просто отримаємо купу нерелевантних для нас результатів. Цей параметр підбирається індивідуально, можна почати зі значення 0.8. А щоб взагалі розуміти, яку оцінку отримав документ і чому якийсь документ взагалі потрапив у видачу, увімкніть дебаг-режим (див. параметр) і через dump()/dd() подивіться відповідь opensearch.

 

SEARCH_DEBUG - вмикає дебаг інформацію (true/false)

 

Встановлення залежностей (повинен бути встановлений composer)

composer install --no-dev --prefer-dist --optimize-autoloader

 

Генеруємо ключ додатка:

php artisan key:generate

 

Коли всі сервіси працюють, можна приступати до налаштування пошуку. Ось перелік консольних команд, як потрібно запустити в корневій директорії API

php artisan search:setup - налаштування семантичного пошуку (тільки для Opensearch)

php artisan search:create-index - створюємо пошуковий індекс

php artisan search:reindex - наповнюємо індекс даними


Опис ключових компонентів:

app/Providers/OpensearchProvider.php - тут конфігурується з'єднання з пошуковою системою і задається схема індексу: поля, їх типи, ваги, опції.

app/Services/Search/Engines/Opensearch/OpensearchIndexer.php - тут конфігурується індекс: маппінг полів, аналізатори, фільтри тощо.

app/Services/Search/Engines/Opensearch/OpensearchSearcher.php - всі налаштування пошуку

app/Console/Commands/Search/Reindex.php - консольна команда, в якій відбувається наповнення індексу даними з бази

 

4. Модуль opencart

Модуль додає autocomplete у форму пошуку і замінює стандартний пошук. Встановлюється модуль як зазвичай. Потім додаємо в config.php налаштування підключення до пошукового API:

define(“API_URL”, “https://ваша_адреса/api/”);
define(“API_TOKEN”, “токен”);

 

search_oc23.ocmod.zip - для opencart 2.3

search_oc3x.ocmod.zip - для opencart 3.x


Все. Пошук готовий до роботи.

 

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

  • +1 6

4 коментаря


Recommended Comments

Какое-то непонятное промо через пень колоду.

 

Все это решается через manticore без танцев с бубном и богомерзкого эластика, который жрет ресурсы, как моя бывшая бабло.

  • +1 2
Надіслати
В 17.09.2025 в 00:10, Yoda сказав:

Все это решается через manticore без танцев с бубном и богомерзкого эластика, который жрет ресурсы, как моя бывшая бабло.

 

Если будет время добавлю поддержку и manticore search.

  • +1 1
Надіслати
В 17.09.2025 в 09:17, ozzzi сказав:

 

Если будет время добавлю поддержку и manticore search.

Так вопрос же не в поддержке. Вопрос в механике процесса. Все через чур сложно. 

 

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

Надіслати
В 17.09.2025 в 15:26, Yoda сказав:

Так вопрос же не в поддержке. Вопрос в механике процесса. Все через чур сложно. 

 

Прокладка тут только одна, это API на фреймворке и лишь по тому что у меня на него еще есть планы, а делать все в рамках opencart мне просто не интересно. А если кому-то делать нечего, но он хотел попробовать что-то новое, может вырезать нужный код и оформить его как полноценный Opencart модуль. 

Надіслати

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

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

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

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

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

Вхід

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

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

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

Important Information

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