Как построить поисковик? (Обновление 2013 года)
Это не первый раз, когда этот вопрос задают здесь, в Stackru, - но это происходит почти пять лет спустя - и времена и технологии немного изменились. Мне интересно, что люди думают в эти дни о создании поисковой системы?
Например, я знаю, что Nutch продолжает развиваться - но все же это самое надежное из доступных решений? Существуют ли альтернативные зрелые решения для других языков - например, C#, PHP, VB.NET?
Я также знаю, что в настоящее время существует общедоступный массовый индекс, который можно использовать, уменьшая необходимость в выполнении собственного паука из Common Crawl.
Конечно, есть еще несколько пользовательских решений для поисковых систем, наиболее известными из которых являются CSE от Google... но я не знаю ни о каких других основных / стабильных / авторитетных решениях, на которые я бы надеялся создать движок?
Какие ресурсы доступны сейчас для изучения программных поисковых систем, которые не были доступны несколько лет назад или даже в прошлом году?
2 ответа
У Udacity есть очень хороший курс по изучению Python с помощью создания веб-сканера, попробуйте его здесь: https://www.udacity.com/course/cs101
Я воспользуюсь этим вопросом, чтобы поделиться опытом написания небольшого поискового движка с нуля (не использовались библиотеки, специфичные для поиска) для довольно небольшого набора данных (он на самом деле ищет stackru, поскольку он не был ни слишком маленьким, ни слишком большим, чтобы работать с ним. один сервер). Проверьте это. Ниже приведены мои выводы на эту тему.
Гусеничный трактор
Во-первых, гусеничный ход - сложная задача. Реальная проблема заключается в записи данных на диск так быстро, как вы получаете веб-страницы. Основная структура данных представляет собой инвертированный индекс, поэтому, когда вы получаете слово "банан", вам нужно извлечь из диска индекс "банан" (список документов, где он находится - вместе с позициями в документе), добавить его к новой записи. и напиши это обратно. По мере того как список растет, его извлечение и запись замедляются. Таким образом, одним из приемов было бы разделение инвертированных индексов (и документов) на разделы, скажем, 1-1000 документов в первом разделе и так далее. Другая "хитрость" заключается в том, что при сканировании раздела следует сохранять индексы в памяти и сбрасывать их на диск только по завершении раздела.
Важный бит: что использовать для хранения данных? Есть много вариантов, и после многих экспериментов я нашел leveldb лучшим выбором на сегодняшний день. И не забывайте SSD диски!
Таким образом, в целом, обход большей части стекового потока (~13 000 000 страниц) таким способом с использованием одной машины (4 Гб оперативной памяти) занимает около 2 месяцев. А результирующие данные (инвертированный индекс, необработанный разделенный текст и т. Д.) - около 80 ГБ дискового пространства.
Поиск
Цель - сделать это быстро и качественно. Нужно понимать, что если вы хотите, чтобы это было быстро, вы не можете искать весь набор данных. К счастью, у меня было все разделено, поэтому поиск занимает первые 100 разделов, где появляются ключевые слова (отдельный индекс для этого), и если он находит "достаточно хорошие" результаты - останавливается, если нет - занимает еще 100 и так далее.
Самая медленная часть - это чтение индексов с диска и десериализация его. Leveldb поддерживает быстрое последовательное чтение, поэтому данные должны храниться так, чтобы большая часть их могла считываться последовательно. Попав в память, пересечение довольно быстрое.
Теперь качество. Это самое сложное и недостаточно хорошее. Моя первая попытка состояла в том, чтобы сохранить инвертированные индексы не только для текста, но также для заголовков, текста ссылок и URL-адресов. Каждое попадание в них добавляет некоторые точки к документу. Другое дело - перефразировать запрос, используя синонимы, и каким-то образом проверить, какой запрос работал лучше всего. Это, вероятно, заслуживает пост в своем собственном.
Во всяком случае, я надеюсь, что это будет полезно для чтения!