Hibernate Search、Lucene或其他替代方案?

10

我有一个查询,对表中的11个字符串或文本字段进行ILIKE操作,该表不是很大(500,000),但对于ILIKE来说太大了,搜索查询需要约20秒。数据库是postgres 8.4

我需要实现这个搜索更快。

我的想法:

  1. 我创建了一个额外的TVECTOR列,从所有需要搜索的列中组装,并在其上创建了全文索引。全文搜索非常快速。但是...我无法在我的.hbms文件中映射此TVECTOR类型。所以这个想法被放弃了(无论如何,我认为它更像是一个临时解决方案)。

  2. Hibernate搜索。(今天第一次听说)它似乎很有前途,但我需要有经验的意见,因为我不想为可能可以更简单地完成的事情而进入新的API,可能不是最简单的API。

  3. Lucene

总之,这种情况现在发生在这个表上,但我希望解决方案更通用,并适用于将来涉及全文搜索的情况。

感谢任何建议!

谢谢

6个回答

12
我强烈推荐使用Hibernate Search,它为Hibernate和Lucene之间提供了一个非常易于使用的桥梁。记住,您将在此处同时使用两者。您只需注释您希望搜索的域类上的属性即可。然后,当您更新/插入/删除启用搜索的实体时,Hibernate Search简单地更新相关索引。这只会发生在提交包含数据库更改的事务时,即如果回滚,索引将不会被破坏。
所以回答您的问题:
1. 是的,您可以在特定表格的特定列上进行索引。您还可以对字段内容进行分词,以便匹配字段的部分。 2. 它并不难使用,您只需确定要搜索的属性,告诉Hibernate在哪里保留其索引,然后可以使用EntityManager/Session接口加载您搜索的实体。

谢谢您的解释,我还有一个简短的问题,我想能够在几个字符串字段上进行搜索。将所有其他字段存储到索引中但不可搜索,然后当我有命中时从那里获取对象,这样做有意义吗?还是应该只获取ID并转到数据库获取它们? - Julia
@Julia 你只需要索引你想要搜索的字段。你告诉Hibernate Search被索引实体的@DocumentId(也可以是@Id)是什么。Hibernate会使用这个id从数据库(或会话缓存)获取实体,而不需要你担心它。实质上,Hibernate Search接受一个搜索字符串,并返回与该搜索匹配的领域实体。很棒,对吧? - Alex Barnes

6

既然您已经在使用Hibernate和Lucene,那么Hibernate Search是一个非常好的选择。

Hibernate Search主要提供的功能是在数据发生更改时更新您的Lucene索引的机制,并利用您已经了解的Hibernate知识来简化对Lucene索引的搜索。

您将能够指定每个实体中要索引的特定字段,并根据需要添加多种类型的索引(例如,分词和全文)。您还将能够管理关联的索引图,以便通过Search/Lucene进行相当复杂的查询。

我发现最好依靠Hibernate Search进行文本搜索,但对于更传统的搜索和为结果显示填充复杂对象图形,最好退回到普通的Hibernate。


0

我推荐使用Compass。它是建立在Lucene之上的开源项目,提供了比Lucene更简单的API。它与许多常见的Java库和框架(如Spring和Hibernate)集成得非常好。


0

我之前曾使用过Lucene来索引数据库表。这个解决方案非常好,但请记住您需要维护索引。您可以每次持久化对象时更新索引,或者您可以使用守护进程索引器将数据库表转储到您的Lucene索引中。

你考虑过Solr吗?它是建立在Lucene之上的,并提供了从DB和Rest API自动索引的功能。


谢谢。我们已经使用Lucene进行文档索引,所以我认为最好坚持使用同一库。使用Lucene如何实现例如我想要索引对象的某些关系?我必须索引整个表格,还是可以只索引我需要的主表和其某些关系的特定列? - Julia
我所采用的方法是使用带有JOIN的SELECT查询来创建我的数据的“平面”结构,以便我可以在其上运行索引器。这是一种方法。您还可以使用存储过程将数据展平为专用于索引目的的特殊表。 - Luciano Fiandesio

0
所有的项目都基于Lucene。如果你想要实现非常高级的功能,我建议你直接使用Lucene。如果不需要那么高级的功能,你可以使用Solr,它是一个强大的API,建立在Lucene之上,可以帮助你从数据库中进行索引和搜索。

我认为我不需要太高级的功能,但是我想避免使用我们迄今未使用过的新库。我不确定我理解你为什么推荐Solr - 它无论如何都是基于Lucene构建的?你能再详细解释一下吗?谢谢! - Julia
我给你举个例子:你需要向Web服务器发起HTTP调用。在Java中,有一个Socket库可以帮助你完成这个任务,但更好的选择是使用Apache Commons HTTP客户端。它内置了实现协议的库,使得操作更加便捷。同样的,Solr也有内置API来管理索引,易于进行全文搜索和数据库集成,并且设计为在Servlet容器上运行。 - Houcem Berrayana

0
一年前我会推荐Compass。它在它所做的事情上表现良好,技术上仍然在我开发和维护的应用程序中愉快地运行。
然而,Compass没有更多的开发,努力转向ElasticSearch。从该项目的网站上,我无法确定它是否已经准备好进入大时代,甚至是否真的还活着。
因此,我正在转向Hibernate Search,虽然这让我感觉不太好,但迁移仍处于初始阶段,所以我将保留判断一段时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接