Полнотекстовый поиск, как Google

Я хотел бы реализовать полнотекстовый поиск в своем автономном (андроидном) приложении для поиска списков заметок, созданных пользователем.

Я бы хотел, чтобы он вел себя так же, как Google (так как большинство людей уже привыкли обращаться к Google)

Мои первоначальные требования:

  • Быстро: как Google или как можно быстрее, имея 100000 документов по 200 ста слов.
  • Поиск двух слов должен только возвращать документы, содержащие оба слова (не только одно слово) (если не используется оператор OR)
  • Нечувствительность к регистру (ака: нормализация): Если у меня есть слово "Hello", и я ищу "привет", он должен совпадать.
  • Диакритическая метка нечувствительна: если у меня есть слово "as", поиск "asi" должен совпадать. На испанском языке многие люди, неверно, либо не ставят диакритические знаки, либо не могут правильно их поместить.
  • Прекратить удаление слова: не иметь большого индекса бессмысленных слов типа 'и', '' или 'для' не следует индексировать вообще.
  • Подстановка словаря (aka: stem words): Подобные слова должны быть проиндексированы как один. Например, примеры "голодных" и "голодных" должны быть заменены "голодом".
  • Поиск фразы: если у меня есть текст "Привет, мир!" поиск "world hello" не должен совпадать, но поиск "мира привет" должен соответствовать.
  • Искать все поля (в многоуровневых документах), если не указано поле (а не только поле по умолчанию)
  • Автозаполнение в результатах поиска при наборе текста, чтобы обеспечить популярные поисковые запросы. (так же, как Google Suggest)

Как настроить полнотекстовый поисковый движок как можно больше, как Google?

(меня больше всего интересуют Open Source, Java и, в частности, Lucene)

Ответ 1

Я думаю, Lucene может удовлетворить ваши требования. Вы также должны рассмотреть возможность использования Solr, который имеет схожие функции и гораздо проще настроить.

Я буду обсуждать каждое требование отдельно, используя Lucene. Я считаю, что Solr имеет схожие механизмы.

  • Быстро: как Google или как можно быстрее, имея 100000 документов по 200 ста слов.

Это разумный размер индекса как для Lucene, так и для Solr, что позволяет извлекать данные за несколько десятков миллисекунд за запрос.

  • Поиск двух слов должен только возвращать документы, содержащие оба слова (не только одно слово) (если не используется оператор OR)

Вы можете сделать это, используя BooleanQuery с MUST по умолчанию в Lucene.

Следующие четыре требования могут быть обработаны путем настройки Lucene Analyzer:

  • Нечувствительность к регистру (ака: нормализация): Если у меня есть слово "Hello", и я ищу "привет", он должен совпадать.

A LowerCaseFilter можно использовать для этого.

  • Диакритическая метка нечувствительна: если у меня есть слово "as", поиск "asi" должен совпадать. На испанском языке многие люди, неверно, либо не ставят диакритические знаки, либо не могут правильно их поместить.

Для этого требуется нормализация Юникода, а затем диакритическое удаление. Вы можете создать для этого пользовательский анализатор.

  • Прекратить удаление слова: не иметь большого индекса бессмысленных слов типа 'и', '' или 'для' не следует индексировать вообще.

A StopFilter удаляет стоп-слова в Lucene.

  • Подстановка словаря (aka: stem words): Подобные слова должны быть проиндексированы как один. Например, примеры "голодных" и "голодных" должны быть заменены "голодом".

У Lucene есть много Snowball Stemmers. Один из них может быть уместным.

  • Поиск фразы: если у меня есть текст "Привет, мир!" поиск "world hello" не должен совпадать, но поиск "мира привет" должен соответствовать.

Это распространяется на специализированный запрос Lucene PhraseQuery.

Как вы можете видеть, Lucene охватывает все необходимые функции. Чтобы получить более общую картину, я предлагаю книгу Lucene in Action, Apache Lucene Wiki или Сайт Lucid Imagination.

Ответ 2

Многие из этих действий по умолчанию для Lucene. Первый (включая все термины) не является, но вы можете заставить это поведение установить оператор по умолчанию:

MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer());
parser.setDefaultOperator(QueryParser.AND_OPERATOR);

Я знаю, что пункты 2, 4 и 6 возможны, а IIRC - по умолчанию. Я не уверен в пунктах 3 и 5, но Lucene предлагает массу вариантов настройки, поэтому я бы предложил внедрить доказательство концепции с вашими данными, чтобы узнать, соответствует ли она этим требованиям.

Ответ 3

Купите Google Search Appliance. Или, как следует из комментариев, используйте Lucene, как вы уже упоминали.

Ответ 4

Если вы не покупаете поисковую систему, у вас есть Lucene, Nutch, Apache Solr и несколько других.

Ответ 5

HyperSQL - это реализация с использованием pure-java SQL, которая может выполняться довольно легко, как и SQLite. Вы можете использовать их полнотекстовые возможности и запросы для воссоздания колеса, но, как другие комментаторы указали, что существующая реализация, вероятно, лучше всего.