Статьи

Поиск в спящем режиме: отображение сущностей

 Все метаданные отображения Hibernate Search описаны в аннотациях. Метаданные Hibernate Search очень ориентированы на код и содержат много информации из структуры классов: аннотации естественным образом подходят и избегают избыточности по сравнению с другими моделями метаданных, такими как XML. Было бы довольно просто добавить поддержку дескриптора развертывания XML для Hibernate Search. Никто не нашел времени и интереса для написания этого слоя (пока что), который, кажется, доказывает, что эта функция не так сильно желана сообществом поиска Hibernate.


Все аннотации Hibernate Search содержатся в пакете org.hibernate.search.annotations.

 Чтобы пометить объект как проиндексированный с помощью Hibernate Search, просто поместите аннотацию @Indexed в классе.

Перечисление 1 Объект индексируется Hibernate Search, когда помечен @Indexed

@Entity
@Indexed
public class Dvd {
...
}

 Из этой единственной аннотации выводится много информации и много работы. Когда Hibernate SessionFactory загружается, Hibernate Search ищет все сопоставленные объекты, помеченные как @Indexed, и обрабатывает их.
Преимущество для нас заключается в том, что нам не нужно явно перечислять проиндексированные объекты в файле конфигурации: это сокращает нашу работу и снижает риск ошибок.

Имя каталога Lucene также выводится из этой аннотации. Поскольку мы не определили явно имя индекса, применяется именование по умолчанию. Имя индекса — это полное имя класса объекта: в нашем примере com.manning.hsia.dvdstore.model.Dvd. Вы можете переопределить это имя, используя атрибут name @Indexed.

Перечисление 2 Индексируемый объект, переопределяющий его имя индекса, чтобы уточнить целевой Каталог Lucene

@Entity
@Indexed(name="Item")
public class Dvd {
...
}

Основное сопоставление между именем индекса поиска Hibernate и физическим каталогом Lucene полностью зависит от поставщика каталога. Давайте рассмотрим два наиболее распространенных сценария: поставщик каталогов в памяти (RamDirectoryProvider) и поставщик каталогов файловой системы (FSDirectroyProvider).
Индексы, использующие RamDirectoryProvider, однозначно идентифицируются по имени индекса для заданного SessionFactory (или EntityManagerFactory, если вы используете постоянство Java). Иначе говоря, Hibernate Search сохраняет экземпляр RamDirectory для каждого имени индекса, когда индекс нацелен на RamDirectoryProvider.
При использовании FSDirectoryProvider имя индекса представляет собой путь к каталогу физической файловой системы. Относительный путь начинается с свойства indexBase.

Совсем безопасно использовать один и тот же физический каталог Lucene для нескольких объектов: Поиск в Hibernate разделяет информацию. Если вы хотите использовать один и тот же физический каталог Lucene для нескольких сущностей, им просто нужно использовать одно и то же значение @ Indexed.name (а также тот же тип DirectoryProvider).

Индексированная сущность перечисления 3, совместно использующая тот же основной каталог Lucene

 

@Entity
@Indexed(name="Item") The same index name is shared by both entities
public class Dvd {
...
}
@Entity
@Indexed(name="Item")
public class Drink {
...
}

 

Должен ли я использовать один и тот же каталог Lucene для всех моих сущностей?
Обычно в этом нет необходимости.
Совместное использование одного и того же индекса поможет оптимизировать запросы, так как Hibernate Search будет обрабатывать меньше ресурсов одновременно. Это особенно верно, когда объем данных индекса невелик. С другой стороны, когда объем данных начинает значительно расти, разделение индекса на несколько поможет Lucene расти. Hibernate Search предлагает такую ​​возможность через то, что называется индексным разделением.
Выигрыш, обеспечиваемый общим доступом к каталогу, обычно не является достаточно значительным, чтобы иметь значение Техническое обслуживание может быть более сильным критерием, но вы можете увидеть стакан наполовину полным или наполовину пустым:

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

Но наличие одного единственного индекса (возможно) сокращает обслуживание.
Как вы можете видеть, не существует явного победителя, и Hibernate Search позволяет вам делать то, что вы предпочитаете. Авторы, как правило, используют настройки поиска по умолчанию в Hibernate и позволяют себе заниматься своим делом. Простота разработки — это действительно то, где выгода

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

Подклассы:

Hibernate Search, как и Hibernate, является полностью полиморфным и позволяет отображать иерархии классов, а также выражать полиморфные запросы. Практически для вас это означает, что вы можете писать классы и подклассы в своей доменной модели, не беспокоясь о Hibernate Search. Возвращаясь к примеру с вашим магазином, наш клиент забыл сообщить нам, что помимо DVD на веб-сайте также должны продаваться продукты питания, такие как попкорн, и напитки, такие как вина. (Я не знаю о попкорне, но я бы был готов заплатить за бокалом приличного вина перед хорошим фильмом). Мы проведем рефакторинг нашей модели предметной области, чтобы соответствовать этому новому требованию. На веб-сайте будут отображаться элементы, которые будут отклонены на DVD, продукты питания и напитки.

Перечисление 4, Отображающее класс и его подкласс

 Hibernate Search будет индексировать не только помеченные свойства данного класса, но и все помеченные свойства его суперкласса. В листинге 4 сущность Drink будет доступна для поиска по следующим свойствам:

  • алкогольный напиток от Drink
  • идентификатор из пункта
  • название из пункта

Вы могли заметить, что объект Item не помечен как @Indexed. Хотя пометка Item с помощью @Indexed не принесет вреда, в этом просто нет необходимости. Вы должны помечать объекты только @Indexed, если:

  • Вы хотите иметь возможность поиска по этой сущности
  • И сущность имеет конкретный тип (не абстрактный).

В нашей системе Item является абстрактным классом и, следовательно, не будет иметь его экземпляров. Подклассы денормализованы в индексе Lucene: все экземпляры Drink будут храниться в индексе org.manning.hsia.dvdstore.model.Drink, включая информацию об идентификаторе свойств его суперкласса и его названии.

Денормализация не мешает вам выполнять полиморфные запросы. Как мы увидим позже в этой книге, вы можете прекрасно искать все предметы, название которых содержит «долину». Появятся вина DVD «В долине Эла» и «Долина Наппа», даже если пункт не был помечен @Indexed.

 Hibernate Search не читает аннотации метаданных из интерфейсов, но вы, конечно, можете отобразить класс реализации и его свойства.

Эта статья основана на главе 3 « Поиск в спящем режиме» Эммануэля Бернарда и Джона Гриффина . Это воспроизводится здесь с разрешения Manning Publications .

Manning early access books and ebooks are sold exclusively through Manning. 
Visit the book's page for more information.