搜索引擎使用技巧有哪些? 全文搜索引擎使用技巧( 三 )


Query phraseQuery = movieQueryBuilder.phrase()
.withSlop(searchPhraseDto.getOtherWordsInPhrase())
.onField("overview")
.sentence(searchPhraseDto.getPhrase()).createQuery();
resultList = fullTextEntityManager
.createFullTextQuery(phraseQuery, Movie.class)
.setMaxResults(1000).getResultList();
}
return resultList;
}

该 *** findMoviesByPhrase(...)具有SearchPhraseDto作为参数 。包含以下属性:

otherWordsInPhrase它的默认值为 0 。
'phrase' 包含 Hibernate Search 索引中电影概览的搜索字符串 。
检查“短语”的存在和长度 。然后FullTextEntityManager创建 和 QueryBuilder 。'QueryBuilder' 用于使用搜索参数'phrase' 在电影实体字段'overview' 上创建全文查询 。与参数一起 otherWordsInPhrase添加到 。FullTextEntityManagerwithSlop(…)

用于对FullTextEntityManager电影 'overview' 索引执行全文查询,结果限制为 1000 个 。设置限制是为了保护服务器免受 I/O 和内存过载的影响 。

使 Hibernate 搜索索引保持最新
在应用程序启动时检查 Hibernate Search 索引以获取CronJobs类中所需的更新:

@Async
@EventListener(ApplicationReadyEvent.class)
public void checkHibernateSearchIndexes() throws InterruptedException {
int movieCount = this.entityManager.createNamedQuery("Movie.count",
Long.class).getSingleResult().intValue();
int actorCount = this.entityManager.createNamedQuery("Actor.count",
Long.class).getSingleResult().intValue();
FullTextEntityManager fullTextEntityManager =
Search.getFullTextEntityManager(entityManager);
int actorResults = checkForActorIndex(fullTextEntityManager);
int movieResults = checkForMovieIndex(fullTextEntityManager);
LOG.info(String.format("DbMovies: %d, DbActors: %d, FtMovies: %d,
FtActors: %d", movieCount, actorCount, movieResults, actorResults));
if (actorResults == 0 || movieResults == 0
actorResults != actorCount || movieResults != movieCount) {
fullTextEntityManager.createIndexer().startAndWait();
this.indexDone = true;
LOG.info("Hibernate Search Index ready.");
} else {
this.indexDone = true;
LOG.info("Hibernate Search Index ready.");
}
}

private int checkForMovieIndex(FullTextEntityManager fullTextEntityManager) {
org.apache.lucene.search.Query movieQuery = fullTextEntityManager
.getSearchFactory().buildQueryBuilder()
.forEntity(Movie.class).get().all().createQuery();
int movieResults = fullTextEntityManager.createFullTextQuery(movieQuery,
Movie.class).getResultSize();
return movieResults;
}

Spring的@Async和@EventListener(ApplicationReadyEvent.class)注解checkHibernateSearchIndexes()在自己的后台线程上执行应用程序启动时的 ***。

首先,使用命名查询来查询数据库中电影和演员实体的数量 。

checkForMovieIndex(...)其次,使用andcheckForActorIndex(...) ***查询 Hibernate Search 索引中的电影和演员实体的数量 。

然后,比较结果,FullTextEntityManager如果发现差异,则重新创建 Hibernate Search 索引 。要获得正常的启动时间,该 *** 必须在其自己的后台线程上执行 。Hibernate Search 索引是文件系统上的文件 。它们需要在第一次启动时创建或检查 。通过在应用程序的每个实例上都有本地索引,可以避免冲突和不一致 。

结论后端
查询有几个可选条件,JPA Criteria 查询支持这个用例 。代码很冗长,需要一些习惯 。替代 *** 是自己创建查询字符串或添加库(可能生成代码)以获得更多支持 。这个项目试图只添加需要的库并且代码是足够可维护的 。我还没有找到同时执行 Hibernate Search 和 JPA 条件查询的支持 。因此,必须在代码中组合结果 。这需要限制结果大小以保护服务器的 I/O 和内存资源,这可能会导致大型结果集中的匹配丢失 。

Hibernate Search 易于使用,并且可以在应用程序启动时创建/更新索引 。