Maven
Hibernate Search provides you with both Lucene and ElasticSearch implementations that are highly optimized for full-text search.
Örnek - Lucene
<dependency>
<groupId>org.Hibernate.search</groupId>
<artifactId>Hibernate-search-mapper-orm</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.Hibernate.search</groupId>
<artifactId>Hibernate-search-backend-lucene</artifactId>
<version>6.0.2.Final</version>
</dependency>
SpringBoot İle KullanımSpring için şu kütüphaneyi dahil
ederizspring-boot-hibernate-search
Index dizinini belirtmek için şöyle
yaparız# HIBERNATE SEARCH
spring.jpa.properties.hibernate.search.backend.directory.root=/home/indexes/
server:
port: 9000
spring:
datasource:
url: jdbc:h2:mem:mydb
username: mozen
password: password
jpa:
open-in-view: false
properties:
hibernate:
search:
backend:
type: lucene
directory.root: ./data/index
Data Model
Entity üzerinde
@Indexed - Sınıfın indeksleneceğini belirtir
@FullTextField - Metin alanlarda arama içindir. Diğer tipte alanlar için başka anotasyonlar var
anotasyonları kullanılır
SearchSession ile arama yapılır
Repository
Spring için şöyle bir kod
ekleriz. Burada
@NoRepositoryBean kullanılıyor, böylece bu sınıf repository olarak
algılanmaz.
@NoRepositoryBean
public interface SearchRepository<T, ID extends Serializable>
extends JpaRepository<T, ID> {
List<T> searchBy(String text, int limit, String... fields);
}
searchBy metodunun gerçekleştirimini ekleriz. Spring kuralları gereği
interface ismine
Impl son ekini vererek yeni bir sınıf yaratırız. Burada
SearchSession hibernate sınıfı. Burada fetch() metoduna limit değeri geçiliyor.
import org.hibernate.search.mapper.orm.session.SearchSession;
@Transactional
public class SearchRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID>
implements SearchRepository<T, ID> {
private final EntityManager entityManager;
public SearchRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
super(domainClass, entityManager);
this.entityManager = entityManager;
}
public SearchRepositoryImpl(
JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Override
public List<T> searchBy(String text, int limit, String... fields) {
SearchResult<T> result = getSearchResult(text, limit, fields);
return result.hits();
}
private SearchResult<T> getSearchResult(String text, int limit, String[] fields) {
SearchSession searchSession = Search.session(entityManager);
SearchResult<T> result = searchSession
.search(getDomainClass())
.where(f -> f.match().fields(fields).matching(text).fuzzy(2))
.fetch(limit);
return result;
}
}
@Repository
public interface PlantRepository extends SearchRepository<Plant, Long> {
}
Örnek - Sayfalama
Şöyle
yaparız. Burada fetch() metoduna offset + limit değerleri geçiliyor.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageDTO<T> {
private List<T> content;
private long total;
}
@Override
public PageDTO<T> searchPageBy(String text, int limit, int offset, String... fields) {
SearchResult<T> result = getSearchResult(text, limit, offset, fields);
return new PageDTO<T>(result.hits(), result.total().hitCount());
}
private SearchResult<T> getSearchResult(String text, int limit, int offset,
String[] fields) {
SearchSession searchSession = Search.session(entityManager);
SearchResult<T> result = searchSession
.search(getDomainClass())
.where(f -> f.match().fields(fields).matching(text).fuzzy(2))
.fetch(offset, limit);
return result;
}