PHP / MySQL — включает множественное число, но исключает единичные числа

#php #mysql

#php #mysql

Вопрос:

Я создаю сайт с требованием включать слова во множественном числе, но исключать однокоренные слова, а также включать более длинные фразы, но исключать более короткие фразы, найденные в нем.

Например:

  • поиск по «хлебам» должен возвращать результаты с «хлебами» внутри него, но не «хлебом» или «чтением».

  • поиск «Книги в мягкой обложке» должен возвращать результаты с «книгой в мягкой обложке» внутри, но не «книгой в мягкой обложке» или «книгой».

Запрос, который я пробовал, это:

 SELECT * FROM table WHERE (field LIKE '%breads%') AND (field NOT LIKE '%bread%')
  

… который явно не дал никаких результатов, хотя в нем есть записи с ‘breads’ и ‘bread’.

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

Комментарии:

1. Английский — неправильный язык. Вам будет сложно получить надежное определение «множественного числа», которое вы можете запросить с помощью простого бита SQL. Кроме того, поиск по шаблону, который вы используете, выполняется очень медленно. Для любой базы данных разумного размера вам придется найти альтернативное решение.

2. Данные в вашей базе данных недостаточно нормализованы. Вам нужно разделить каждый текст на слова и отметить для каждого слова, является ли оно единственным или нет. Тогда вы можете искать только слова в единственном числе в текстах.

3. % — это дикий символ, который соответствует любой вещи, поэтому будьте осторожны при использовании в подобной ситуации.

4. … вверху была заметка о том, что это была переписка — не знаю, возможно ли слияние?

5. @CD001: отредактируйте свой исходный вопрос, чтобы добавить новую информацию.

Ответ №1:

Поиск %breads% НИКОГДА НЕ вернет bread или read , поскольку «s» является обязательным символом для соответствия. Так что просто исключите предложение and:

 SELECT ... WHERE (field LIKE '%breads%')
SELECT ... WHERE (field LIKE '%paperback book%');
  

Комментарии:

1. Я считаю, что использование подстановочных знаков здесь бесполезно. Допустим, вы используете '%read%' , теперь это также вернет bread breads и т.д., Поэтому я рекомендовал полнотекстовый поиск

2. Верно, но на этом этапе, когда вы ищете слова меньшего размера, вы можете использовать дополнительные биты «и не». Для более длинных слов, которые не могут отображаться в сокращенной форме, это упрощенное предложение where работает нормально.

Ответ №2:

Вам следует рассмотреть возможность использования ПОЛНОТЕКСТОВОГО ПОИСКА.

Это решит вашу проблему с хлебом / чтением.

Я считаю, что использование подстановочных знаков здесь бесполезно. Допустим, вы используете '%read%' , теперь это также вернется bread и т. breads Д., Поэтому я рекомендовал Full Text Search

Комментарии:

1. Хотя это не позволяет вам использовать таблицы InnoDB.

Ответ №3:

С MySQL вы можете использовать РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ вместо like, что даст вам лучший контроль над вашим запросом…

 SELECT * FROM table WHERE field REGEXP 's reads '
  

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