1

Есть много текстов, штук 500, каждый размером с книгу. Как оптимально организовать поиск точной фразы, вводимой пользователем, по этим текстам с помощью c#? Скорость важна, тексты всегда одни и те же.

UPD. А если я разобью все тексты на предложения, можно будет как то ускорить поиск с помощью БД, например?

Maksim
  • 67
  • Загрузить тексты в БД, использовать полнотекстовый поиск. – Alexander Petrov Jun 06 '16 at 20:18
  • @AlexanderPetrov, ради всего 500 текстов не рационально заводить полноценную БД. Это несет лишние издержки на обслуживание. – Alexis Jun 06 '16 at 20:46
  • 1
    Если фраза должна состоять точно из слов текстов, то можно сделать индекс слов с их смещениями в тексте и построить поиск, использующий этот индекс. – avp Jun 06 '16 at 22:31
  • @AlexanderPetrov это быстрее будет чем без БД? – Maksim Jun 07 '16 at 07:54
  • @avp фразы может и не быть в текстах и можно ссылку что за индекс со смещениями? – Maksim Jun 07 '16 at 07:56
  • Использование базы данных для данных, которые помещаются в память, не ускорит, а скорее всего и замедлит поиск. Ваш К. О. – VladD Jun 07 '16 at 12:35
  • 1
    Ссылку на то, что такое индекс? Наверное можно найти в гугле, лучше почитать что-нибудь про реализацию баз данных (если найдете). Вообще, у вас индекс это структура данных, где слово это ключ, а адресуемые ими данные это смещения от начала текста, где данное слово встречается. Наверное для такой задачи с каждым словом (ключем в индексе) стоит хранить и количество мест, где оно встречается. Это позволит при анализе по словам фразы выбрать наиболее редко встречающееся слово и читать только те места текста, где оно есть. Соответственно, меньше текста сравнивать с другими словами фразы. – avp Jun 07 '16 at 13:18

3 Answers3

5

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

Если в вашем проекте уже используется какая-либо СУБД, поддерживающая полнотекстовый поиск, то логично использовать её. В противном случае, следует поискать какой-либо поисковый движок.

Одним из наиболее известных поисковых движков является Lucene. Устанавливать проще всего с помощью nuget. Пример использования в .NET.
Можно посмотреть на hOOt.


Всегда ли это будет быстрее, чем тупой перебор текстовых файлов? Нет. Однако, даже если количество и размер файлов относительно невелики и они могут целиком уместиться в ОЗУ, то всё равно использование индекса может оказаться быстрее: ведь в большинстве случаев загрузка файлов вообще не понадобится.

1

Загрузить тексты в потокобезопасную очередь (ConcurrentQueue например), поднять 500 потоков, и в них проверять тексты из очереди, где каждый текст проверяется в своем потоке. Так же есть разные варианты с асинхронными задачами, циклами Parallel.For, Linq.ForEach и т.д.

Приводить примеры кода без конкретики бессмысленно.

Alexis
  • 3,476
  • Зачем 500 потоков? – Alexander Petrov Jun 06 '16 at 20:15
  • @AlexanderPetrov, не обязательно потоков, можно асинхронных задач. Вот к примеру: http://ru.stackoverflow.com/questions/503721/%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B5-vs-%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BD%D0%B0-%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B5 – Alexis Jun 06 '16 at 20:22
1

Как вариант использовать Lucene,есть порт на .net Lucenenet. Индекс сделать заранее, и из приложения искать по нему нужный документ. Вот ещё ссылка Introducing-Lucene-Net