Hibernate Search:搜索

时间:2017-03-09 08:50:44

标签: hibernate lucene hibernate-search

我正在通过Hibernate Search和Lucene实现全文搜索功能。搜索看起来像这样,效果很好。我的问题是我们的实体类大多非常庞大,因此提供100个结果的搜索需要太长时间,因为查询找到的实体非常耗时。

打开表单时,我使用HQL查询加载最后20个已编辑的实体,这也是首先花费的时间太长,所以我创建了一个实体,其中只包含我需要在结果列表中显示的字段和ID实际的实体。仅当用户单击结果以详细查看结果时,才会加载实际实体。这加快了查询时间到原来时间的1/100和更少。

有没有办法以同样的方式加速Hibernate Search查询,所以我搜索一个实体,但只查询对象的ID而不是整个实体?

EntityManager em =  EntityManagerUtil.getEntityManager();

List<T> returnList=new ArrayList<>(); 

FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
em.getTransaction().begin();

QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(typeParameterClass).get();
TermMatchingContext onFields = qb.keyword().wildcard().onFields(getSearchFields()); 

BooleanJunction<BooleanJunction> bool = qb.bool();
org.apache.lucene.search.Query query = null;

String[] searchTerms = searchString.split("\\s+");
for (int j = 0; j < searchTerms.length; j++) {
    String currentTerm = searchTerms[j];
    bool.must(onFields.matching(currentTerm).createQuery());
}

query = bool.createQuery();

javax.persistence.Query persistenceQuery = fullTextEntityManager.createFullTextQuery(query, typeParameterClass);
persistenceQuery.setMaxResults(100);

returnList = persistenceQuery.getResultList(); 

2 个答案:

答案 0 :(得分:1)

您可以使用Index Projections让查询仅返回选定的属性。 ID是一个选项:

javax.persistence.Query persistenceQuery = fullTextEntityManager.createFullTextQuery(query, typeParameterClass);
query.setProjection(ProjectionConstants.ID, [other fields...])
persistenceQuery.setMaxResults(100);

这将使您的查询返回数组。数组的第一个元素将包含每个匹配的ID。

您也可以加载其他字段,只要它们已使用

标记为已存储
@Field(store=Store.YES)

始终存储ID,因此如果您只想投影ID,则无需添加此ID。

顺便说一句,如果您的加载时间很短,那么您的映射会出现问题。我猜你有太多急切的关系被加载。一般建议是将大部分映射为懒惰,并使用一些二级缓存是合适的。

答案 1 :(得分:0)

您需要org.hibernate.search.jpa.FullTextQuery而不是javax.persistence.Query

org.hibernate.search.jpa.FullTextQuery persistenceQuery = fullTextEntityManager.createFullTextQuery(query, typeParameterClass);
persistenceQuery.setProjection(ProjectionConstants.ID);
persistenceQuery.setMaxResults(100);