В настоящее время я работаю над индексом для функции поиска. Индексатор будет работать над данными из «полей». Поля выглядят так:
Field_id Field_type Field_name Field_Data - 101 text Name Intel i7 - 102 integer Cores 4 physical, 4 virtual - 103 select Vendor Intel - 104 multitext Description The i7 is intel's next gen range of cpus.
Индексатор будет генерировать следующие результаты / индекс:
Keyword Occurrences - intel 101, 103, 104 - i7 101, 104 - physical 102 - virtual 102 - next 104 - gen 104 - range 104 - cpus 104 (*) - cpu 104 (*)
Так что это выглядит очень красиво и прекрасно, однако есть некоторые проблемы, которые мне хотелось бы разобраться:
(кстати, я не склонен к интеллекту, просто бывает, что у меня есть i7-based pc ;-))
Это ответ на ваш первоначальный вопрос и ваш более поздний ответ / вопрос .
Я использовал поисковую систему Sphinx раньше (довольно давно, так что я немного ржавый) и нашел, что это очень хорошо, даже если документации иногда немного не хватает.
Я уверен, что есть другие способы сделать это, как с вашим собственным кодом, так и с другими поисковыми системами. Сфинкс просто оказался тем, который я использовал. Я не предлагаю, чтобы он сделал все, что вы хотите, именно так, как вы хотите, но я уверен, что он будет делать большую часть этого довольно легко и намного быстрее, чем все, что написано только в PHP / MySQL.
Я рекомендую прочитать Построение пользовательской поисковой системы с PHP, прежде чем вникать в документацию Sphinx . Если вы не считаете это подходящим после прочтения этого, достаточно справедливым.
Отвечая на ваши конкретные вопросы, я собрал некоторые ссылки из документации вместе с некоторыми соответствующими цитатами:
отфильтровывая общие слова (как вы, возможно, заметили, «из списка» отсутствуют «« есть »и« intel »,
11.2.8. игнорируемые слова
Стоп-слова – это слова, которые не будут индексироваться. Как правило, вы добавляете наиболее часто используемые слова в список стоп-слов, потому что они не добавляют большого значения результатам поиска, а потребляют много ресурсов для обработки.
Что касается «cpus» (множественные числа и особые числа), было бы лучше использовать конкретный тип (единственное или множественное число), то и другое (то есть, «cpus» – это «cpu»)?
11.2.9. словоформы
Формы Word применяются после токенирования входящего текста правилами charset_table. Они существенно позволяют заменить одно слово другим. Как правило, это будет использоваться для приведения различных форм слов в одну нормальную форму (например, для нормализации всех вариантов, таких как «прогулки», «прогулки», «ходьба» в обычную «прогулку»). Он также может быть использован для реализации исключений исключения, потому что ограничение не применяется к словам, найденным в списке форм.
Продолжая предыдущий пункт, как я могу определить множественное число (разные вкусы: test => тесты fish => рыба и листья => листья)
Sphinx поддерживает алгоритм Stormming Porter
Построчный алгоритм Портера (или «Портер-стример») – это процесс удаления общих морфологических и флексиальных окончаний из слов на английском языке. Его основное использование является частью процесса нормализации термина, который обычно выполняется при настройке систем поиска информации.
Предположим, я хотел использовать термин поиска «vendor: intel», где поставщик указывает имя поля (имя_поля), как вы думаете, что будет иметь огромное влияние на сервер sql?
3.2. Атрибуты
Хорошим примером атрибутов будет таблица сообщений на форуме. Предположим, что только поля заголовка и содержимого должны быть доступны для полнотекстового поиска, но иногда также требуется ограничить поиск определенным автором или подфорумом (т. Е. Искать только те строки, которые имеют определенные значения author_id или forum_id столбцы в таблице SQL); или сортировать совпадения столбцом post_date; или группировать совпадающие записи по месяцам post_date и подсчитывать количество совпадений в каждой группе.
Этого можно достичь, указав все упомянутые столбцы (исключая заголовок и контент, которые являются полнотекстовыми полями), как атрибуты, индексируя их, а затем используя вызовы API для настройки фильтрации, сортировки и группировки.
Вы также можете использовать 5.3. Расширенный синтаксис запросов для поиска определенных полей (в отличие от фильтрации результатов по атрибутам):
оператор поиска по полю: @vendor intel
Как поисковая система индексирует набор полей и связывает найденные фразы / ключевые слова / etc с конкретным идентификатором поля?
8.6.1. запрос
При успешном выполнении Query () возвращает набор результатов, содержащий некоторые найденные совпадения (по запросу SetLimits ()) и дополнительную общую статистику по каждому запросу. > Результирующий набор является хешем (специфичным для PHP, другие языки могут использовать другие структуры вместо хэша) со следующими ключами и значениями:
"Матчи":
Хэш, который отображает найденные идентификаторы документов в другой небольшой хэш, содержащий вес и значения атрибута документа (или массив подобных небольших хэшей, если включен SetArrayResult ())."Всего":
Общее количество совпадений, полученных на сервере (т. Е. С помощью набора результатов на стороне сервера) по этому запросу. Вы можете получить до этого количества совпадений от сервера для этого текста запроса с текущими настройками запроса."Total_found":
Общее количество совпадающих документов в индексе (которые были найдены и обработаны на сервере).«слова»:
Хеш, который сопоставляет ключевые слова запроса (сложенные, связанные, обработанные иным способом) с небольшим хэшем с статистикой по ключевым словам («документы», «хиты»)."ошибка":
Сообщение об ошибке запроса, сообщаемое поиском (строка, читаемая человеком). Пусто, если ошибок не было."предупреждение":
Предупреждающее сообщение о запросе, отправленное поисковым запросом (строка, считываемая человеком). Пусто, если не было предупреждений.
Также см. Листинг 11 и листинг 13 из « Создание пользовательской поисковой системы с помощью PHP» .
Возьмите список слов остановки (не ключевые слова) отсюда, парень даже отформатировал их в php для вас. http://armandbrahaj.blog.al/2009/04/14/list-of-english-stop-words/
Затем просто выполните preg_replace в строке, которую вы индексируете.
То, что я делал в прошлом, это удалить суффиксы типа 's', 'ed' и т. Д. С помощью регулярного выражения и использовать одно и то же регулярное выражение в строке поиска. Однако это не идеально. Это было для базового сайта с 200 страницами.
Если вас беспокоит производительность, вы можете рассмотреть возможность использования поисковой системы, такой как Lucine (solr), а не базы данных. Это упростит индексирование. Вы не хотите изобретать велосипед здесь.
отфильтровывая общие слова (как вы, возможно, заметили, «из списка» отсутствуют «« есть »и« intel »,
Найдите (или создайте) список общих слов и отфильтруйте ввод пользователя.
Что касается «cpus» (множественные числа и особые числа), было бы лучше использовать конкретный тип (единственное или множественное число), то и другое (то есть, «cpus» – это «cpu»)?
Зависит. Я бы искал и то и другое, если это не большая нагрузка; или для единственной формы, используя предложение LIKE, если это возможно.
Продолжая предыдущий пункт, как я могу определить множественное число (разные вкусы: test => тесты fish => рыба и листья => листья)
Создайте метод или класс Inflector. т.е.: Inflect::plural('fish')
дает вам 'fish'
. Там могут быть такие классы для английского языка, искать их.
В настоящее время я использую MySql, и я очень обеспокоен проблемами производительности; у нас есть более 500 категорий, и мы даже не запустили сайт
Хорошая схема и дизайн кода помогают, но я не могу дать вам много советов по этому поводу.
Предположим, я хотел использовать термин поиска «vendor: intel», где поставщик указывает имя поля (имя_поля), как вы думаете, что будет иметь огромное влияние на сервер sql?
Это действительно поможет, так как вы будете искать один столбец вместо нескольких. Просто будьте осторожны, чтобы фильтровать ввод пользователя и / или разрешить просмотр только определенных столбцов.
Поиск дросселирования; Мне это совсем не нравится, но это возможность, и если вы знаете какие-нибудь обходные пути, сделайте себе услышанное!
Здесь не так много вариантов. Чтобы помочь здесь и в производительности, вы должны рассмотреть возможность своего рода кэширования.
Я бы сердечно предложил вам взглянуть на Солра. Это основанная на Java система поиска и индексирования и, вероятно, имеет больше преимуществ, чем решение PHP.
Поиск трудно реализовать. Порекомендовал бы использовать пакет, если вы новичок в нем.
Рассматривали ли вы http://framework.zend.com/manual/en/zend.search.lucene.html ?
Поскольку многие предлагают использовать существующий пакет (и я хочу сделать это сложнее для вас, чем просто предложить пакет ;-)), давайте предположим, что я буду использовать такой пакет (в этом потоке ответов).
Как поисковая система индексирует набор полей и связывает найденные фразы / ключевые слова / etc с конкретным идентификатором поля? Это не вопрос, на который я хочу ответить, по крайней мере, не напрямую. Моя проблема в том, насколько легко заставить поисковую систему работать так, как я хочу? Учитывая мои вышеуказанные требования, возможно ли это и возможно?
Из личного опыта я предпочел бы потратить некоторое время на настройку своей системы, вместо того, чтобы фиксировать чужой код, и мне приходится тратить больше времени на то, чтобы понять сначала. Назовите меня консервативным, но я редко придерживаюсь чужих кодов / программ, и когда я это делал, это было из-за отчаянной ситуации – и я обычно в конечном итоге каким-то образом способствовал указанному проекту.
На PHP / ir есть PHP-реализация части Brill Part of Speech. Это может служить основой для идентификации тех слов, которые должны быть отброшены, и тех, которые вы хотите индексировать, а также идентифицирует множественные числа (и корень единственного числа). Это не идеально, хотя пользовательский словарь для обработки технических терминов, он может оказаться полезным для решения ваших первых трех вопросов.