Проект Symfony 3.4. Как добавить функцию поиска?

Я разрабатываю проект Symfony 3.4. Он состоит из нескольких наборов: очень простого блога (блоги / сообщения / комментарии), веб-страниц (страниц / содержимого) и чего-то, что может показывать временные рамки (временные шкалы / события). Теперь я хочу добавить кнопку поиска и способ, позволяющий пользователю запрашивать базовые данные из всех этих сущностей.

Позвольте мне объяснить себя очень простым сценарием. Пользователь ищет «тупой» и говорит, что «тупой» встречается в нескольких записях поста (в поле «сообщение» и «заголовок»), паре записей событий (поле «описание») и нескольких записях контента (...). Мне нужно вернуть список ссылок на разные представления, скажем, на blog / post / 1 / show, ..., page / content / 27 / show, ..., timeline / event / 19 / show, ... .

Думаю, я мог бы сделать это по частям с помощью простого php + sql. Вопрос в том, есть ли что-то готовое к работе, такое, что мне просто нужно его настроить?

В противном случае мне лучше индексировать свои данные?

Я вижу, что для индексации данных Symfony предлагает Algolia, но это кажется тяжелым решением для моего простого проекта. (Кроме того, я понимаю, что Algolia - это не то, на чем я могу запускать свой сервер, не так ли?)

Я тоже вижу FOSElasticaBundleЭластика), но не уверен, обновляется ли он до сих пор. Также вроде бы был какой-то проблемы с безопасностью.

Используйте простую форму

Albeis 09.07.2018 19:26

@Albeis, да, я отредактировал, чтобы лучше объяснить себя.

mario 09.07.2018 19:55

Я считаю, что у Algolia есть бесплатный вариант, который в некоторой степени идеально подходит для небольшого проекта. Тем не менее, мой совет: используйте собственный простой поиск, потому что у вас, вероятно, не будет большого количества данных и, следовательно, нет необходимости индексировать их за пределами. Когда вы освоитесь со своим проектом и решите немного его расширить, попробуйте Algolia, реализовать его в любом случае довольно просто.

Domagoj 09.07.2018 20:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
3
377
1

Ответы 1

Для такого простого проекта без множества параметров поиска и без каких-либо особых требований я бы просто использовал простую форму Symfony и напрямую запросил бы БД.

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


Редактировать:

Простой подход состоит в том, чтобы выполнить соединение всех таблиц, которые вы хотите запросить, выполнить LIKE '% myfilter%' для всех текстовых полей, которые вы хотите проверить, получить идентификатор объекта, передать их в twig, а затем в цикле получить путь к контроллеру представления сущности, передав ему параметр id. Это должно работать очень хорошо, если ваша схема проста и у вас относительно мало записей. В таком случае я бы придерживался LIKE и избегал использования полнотекстовых индексов (..WHERE MATCH (content) AGAINST ...), потому что mysql очень медленно объединяет такие индексы с другими в сложных запросах с соединениями.

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

Это также может открыть путь к более легкому переключению на другой индексатор / поисковую систему (когда придет время), поскольку вы уже проделали некоторую работу, чтобы отделить поиск / индексирование от структуры вашей реальной модели.

да, скорее всего. См. Редактировать. Будем рады, если вы расскажете немного о том, как «напрямую запрашивать».

mario 10.07.2018 11:08

Я добавил несколько более подробных простых подходов. Проверьте мою правку выше. Дай мне знать, если тебе еще понадобится помощь :)

Dimitris 10.07.2018 12:10

@ Димитрис большое спасибо. Я попробую сериализованное полнотекстовое представление, мою новую домашнюю работу, и вернусь. Вы знаете какой-нибудь хороший учебник?

mario 10.07.2018 12:34

Это должно быть прямо. Ваша самая большая проблема будет заключаться в том, чтобы решить, как сериализовать ваши объекты (возможно, json). Ознакомьтесь с руководствами по сериализатору symfony и jms. Затем я бы создал события (новые / обновление / удаление) и слушателей и отправлял их каждый раз, когда в вашем объекте вносятся изменения. Избегайте использования событий жизненного цикла доктрины и слушателей. Они плохо работают со смывом в них. И тогда вы должны использовать собственный sql для поиска. Таким образом, вы можете выполнять полнотекстовые запросы в mysql. Doctrine не поддерживает их, так как они зависят от производителя. Пожалуйста, отправьте обратно то, что вы выбрали :)

Dimitris 10.07.2018 12:47

Кстати, если вы обнаружите, что пытаетесь добавить другие параметры поиска, такие как тип, бренд, модель и т. д., Вы можете подумать о переходе на postgresql и использовании запросов jsonb. Они будут бесконечно быстрее и проще кодировать

Dimitris 10.07.2018 13:17

@ Димитрис Привет, нужна помощь по части сериализации. Пробую jms. В одном из своих контроллеров я пробую: $serializer = \JMS\Serializer\SerializerBuilder::create()->build(); $serializer->serialize($myEntity, 'json'); $eventDispatcher = $this->get('event_dispatcher'); $eventDispatcher->dispatch( 'basic.event.name', new BasicEvent() )->eventdump($serializer); (eventdump () просто сбросить!) Что дальше? Насколько я понимаю, вы предлагаете сохранить мои данные в новой таблице. Вы имеете в виду, что мне нужно создать новый класс Entity? и что я должен на этом экономить? Мне нужно десериализовать?

mario 11.07.2018 16:54

Вам нужна переменная для хранения сериализованного объекта. Когда вы выполняете $ jsonContent = $ serializer-> serialize ($ data, 'json'), вы в основном получаете строковое представление своей сущности. А затем вы можете сохранить его в новой таблице «поиска», используя новую сущность, или в столбце в своей основной таблице сущностей. Все, что плывет на вашей лодке.

Dimitris 11.07.2018 17:04

var_dump (сериализованная сущность $jsonContent) - это огромное количество дополнительных данных. Как выделить то, что хочу / нужно? В общем, если у меня есть несколько сущностей (и гораздо больше контроллеров CRUD), нужно ли мне отправлять / прослушивать каждую из них в рамках каждого отдельного действия? Есть ли способ сделать это централизованно?

mario 11.07.2018 21:36

Чтобы выбрать данные Cherrypick, вы можете выбрать либо собственный sql, либо построитель запросов с частичными сущностями. Я бы, наверное, использовал собственный sql. Чтобы обрабатывать его централизованно, я бы создал настраиваемое событие, которое отправлял бы каждый раз при изменении одной из сущностей (передавая ей идентификатор центральной сущности). А затем обработайте обновление таблицы поиска на слушателе, который получает идентификатор центрального объекта из события и выполняет фактическое соединение / сериализацию / сохранение новых данных.

Dimitris 11.07.2018 23:58

Да, и хороший способ централизованно запускать индексацию, не отправляя ее вручную на каждом контроллере, вы можете подключиться к событию onFlush Doctrine, проверить единицу работы, если она содержит какие-либо объекты, которые вас интересуют, и затем запустить свое настраиваемое событие. Только будьте осторожны, чтобы не смыться. И слушатель может накладывать небольшие накладные расходы на все ваши флеши. Проверьте эту тему, чтобы узнать больше stackoverflow.com/questions/51289918/…

Dimitris 12.07.2018 15:04

Другие вопросы по теме