Решения для полнотекстового поиска для Java? - PullRequest
2 голосов
/ 25 сентября 2011

Существует большой набор сущностей разных видов:

interface Entity {
}

interface Entity1 extends Entity {
  String field1();
  String field2();
}

interface Entity2 extends Entity {
  String field1();
  String field2();
  String field3();
}

interface Entity3 extends Entity {
  String field12();
  String field23();
  String field34();
}

Set<Entity> entities = ...

Задача - реализовать полнотекстовый поиск для этого набора. Под полнотекстовым поиском я имею в виду, что мне просто нужно получить объекты, содержащие искомую подстроку (мне не нужно нужно знать точное свойство, точное смещение, где находится эта подстрока и т. Д.). В текущей реализации интерфейс Entity имеет метод matches(String):

interface Entity {
  boolean matches(String text);
}

Каждый класс сущностей реализует его в зависимости от своих внутренних функций:

class Entity1Impl implements Entity1 {
  public String field1() {...}
  public String field2() {...}

  public boolean matches(String text) {
    return field1().toLowerCase().contains(text.toLowerCase()) ||
           field2().toLowerCase().contains(text.toLowerCase());
  }
}

Я считаю, что этот подход действительно ужасен (хотя он работает). Я рассматриваю возможность использования Lucene для создания индексов каждый раз, когда у меня есть новый набор. Под индексом я имею в виду content -> id mappings. Содержание - это просто тривиальная «сумма» всех полей, которые я рассматриваю. Таким образом, для Entity1 содержимое будет представлять собой объединение field1() и field2(). У меня есть некоторые сомнения по поводу производительности: создание индекса часто является довольно дорогой операцией, поэтому я не совсем уверен, поможет ли это.

У вас есть другие предложения?

Чтобы уточнить детали:

  1. Set<Entity> entities = ... из ~ 10000 наименований.
  2. Set<Entity> entities = ... не читается из БД, поэтому я не могу просто добавить условие where .... Источник данных довольно нетривиален, поэтому я не могу решить проблему с его стороны.
  3. Entities следует рассматривать как короткие статьи, поэтому некоторые поля могут занимать до 10 КБ, а другие - ~ 10 байт.
  4. Мне нужно выполнять этот поиск довольно часто, но и строка запроса, и исходный набор каждый раз различаются, поэтому похоже, что я не могу просто создать индекс один раз (потому что набор сущностей каждый раз отличается).

Ответы [ 2 ]

2 голосов
/ 25 сентября 2011

Я бы настоятельно рекомендовал использовать Lucene с SOLR.http://lucene.apache.org/java/docs/index.html

1 голос
/ 26 сентября 2011

Для такой сложной предметной области вы можете использовать инструмент-оболочку lucene, например Compass , который позволяет быстро отобразить график объекта в индекс lucene, используя тот же подход, что и ORM (например, в спящем режиме)

...