Как реализовать функцию поиска?

#javascript #php #android #mysql

#javascript #php #Android #mysql

Вопрос:

В моей таблице есть поле keywords, в котором хранятся все ключевые слова, разделенные запятыми. Теперь у меня есть входное слово, и я хочу выполнить поиск по всем элементам из таблицы, соответствующим этому вводу, используя поля ключевых слов в таблице. Есть ли лучший способ сделать это или единственный способ — линейный поиск по всей таблице.

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

1. Все, что вам нужно сделать, это выполнить поиск по всем элементам из таблицы, соответствующим этому вводу, используя поля ключевых слов в таблице.

2. поле keywords в моей таблице, в котором хранятся все ключевые слова, разделенные запятыми , нормализуют его (keyword_group_id, ordinal_position, one_keyword) .

3. @GrumpyCrouton да, я понимаю, но я спрашивал, есть ли другой способ

4. @Akina не могли бы вы подробнее рассказать, пожалуйста. Используя пример, если это возможно

5. @dhruvtailor Откуда нам знать? Вам необходимо предоставить более подробную информацию. Разбейте структуру соответствующих таблиц, предоставьте нам примеры данных, примеры поиска, пример ожидаемых результатов

Ответ №1:

Пример.

Теперь у вас есть хранилище, которое выглядит как:

 group_id | keywords
-----------------------------------------
   ...   |  ...
   123   |  word1,word2,word3
   124   |  word5,word2
   125   |  word3,word4,word1,word7,word8
   ...   |  ...
  

Вы преобразуете его в

 group_id | ordinal | keyword
----------------------------
   ...       ...     ...
   123        1      word1
   123        2      word2
   123        3      word3
   124        1      word5
   124        2      word2
   125        1      word3
   125        2      word4
   125        3      word1
   125        4      word7
   125        5      word8
   ...       ...     ...
  

Когда вам нужен идентификатор группы для групп, который содержит, например, 'word2' , вы выполняете

 SELECT group_id 
FROM keywords
WHERE keyword = 'word2'
  

который вернет

 group_id
--------
  123
  124
  

И когда вам нужны целые группы ключевых слов, которые вы выполняете

 SELECT group_id, GROUP_CONCAT(group_id ORDER BY ordinal) keywords
FROM keywords
JOIN ( SELECT group_id 
       FROM keywords 
       WHERE keyword = 'word2' ) AS groups USING (group_id)
  

который вернет

 group_id | keywords
-------------------------------
   123   |  word1,word2,word3
   124   |  word5,word2
  

Чтобы повысить производительность, вы бы создали соответствующие индексы ( (keyword, group_id) постепенно (group_id) ) в структуре таблицы.

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

1. У меня был бы соблазн переместить вашу структуру ссылок в формат «многие ко многим», где вы можете хранить исходный идентификатор таблицы, порядковую позицию и идентификатор слова (PK для обоих идентификаторов). Тогда ваша таблица word может иметь уникальный индекс для слова, что ускорит поиск.

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

3. ах, я понимаю, откуда вы. Я бы лично рассматривал слова как неизменяемые и не «принадлежащие» ни к одной из записей в левой таблице. Поэтому, если кто-то «удаляет» слово, оно удаляет m2m. Если слово «отредактировано», то m2m удаляется и создается заново для нового слова (независимо от того, было ли оно вставлено или уже есть).

Ответ №2:

Я собираюсь рекомендовать использовать выделенный поисковый индекс. Ответ Акины отлично подходит для выполнения этого полностью внутри MySQL. Если вы хотите сопоставить Dave like '%ave%' , вам нужно ознакомиться с FULLTEXT индексами; Руководство по MySQL.

Однако с помощью этой структуры вы только что создали половину поискового индекса. Для вас было бы лучше ввести реальный индекс поиска в свой стек. В наши дни Elastic действительно легко реализовать с помощью библиотек для Laravel и Symfony или просто с помощью драйвера PHP (требуется некоторая сборка). Как только у вас будет индекс поиска, он предоставит дополнительные преимущества, такие как автоматическое множественное число поисковых запросов, и даже вернет ваши результаты, упорядоченные по количеству совпадений.

Все, что вам нужно сделать, это создать индекс поиска, содержащий одно поле и пробел — разделите все ваши слова в нем для каждой записи в вашей базе данных MySQL. Тогда ваша эластичная запись будет выглядеть следующим образом:

 {
    "_id": "[Elastic's record ID]",
    "mysql_id": "[Your ID in MySQL]",
    "search_field": "word1 word2 word3"
}
  

Поиск по этому индексу вернет вам идентификаторы MySQL для поиска, которые затем вы можете использовать обратно в своем PHP-приложении.