【问题标题】:Hibernate Search, Lucene or any other alternative?Hibernate Search、Lucene 或任何其他替代方案?
【发布时间】:2011-09-01 17:54:09
【问题描述】:

我有一个查询,它在表的一些 11 个字符串或文本字段上执行 ILIKE,这不是很大 (500 000),但是对于 ILIKE 显然太大了,搜索查询大约需要 20 秒。数据库是 postgres 8.4

我需要更快地实现此搜索。

我想到了什么:

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

  2. 休眠搜索。 (今天第一次听说)这似乎很有希望,但我需要有经验的意见,因为我不想进入新的 API,可能不是最简单的,因为可以做更简单的事情。

    李>
  3. Lucene

无论如何,这个表现在已经发生了,但我希望解决方案更通用,并应用于与全文搜索相关的未来案例。

感谢所有建议!

感谢

【问题讨论】:

    标签: java hibernate lucene full-text-search hibernate-search


    【解决方案1】:

    我强烈推荐 Hibernate Search,它在 Hibernate 和 Lucene 之间提供了一个非常易于使用的桥梁。请记住,您将在这里同时使用这两种方法。您只需在您希望能够搜索的域类上注释属性。然后,当您更新/插入/删除启用搜索 Hibernate Search 的实体时,只需更新相关索引。仅当发生数据库更改的事务已提交时才会发生这种情况,即如果它回滚,则索引不会被破坏。

    所以回答你的问题:

    1. 是的,您可以索引特定表上的特定列。您还可以对字段的内容进行标记,以便匹配字段的某些部分。

    2. 使用起来并不难,您只需确定要搜索的属性即可。告诉 Hibernate 在哪里保存它的索引。然后就可以使用EntityManager/Session接口来加载你搜索过的实体了。

    【讨论】:

    • 感谢解释,还有一个简短的问题,我希望能够搜索几个字符串字段。将所有其他字段也存储到索引中是否有意义,但不可搜索,然后当我点击时,我从那里获取对象,或者我应该只获取 IDS 并转到数据库获取它们?
    • @Julia 您应该只索引您想要搜索的字段。你告诉 Hibernate Search 索引实体的@DocumentId(也是@Id)是什么。然后 Hibernate 将使用这个 id 从数据库(或会话缓存)中获取实体,而您无需担心它。实际上,Hibernate Search 接受一个搜索字符串并返回与该搜索匹配的域实体。整洁吧?
    【解决方案2】:

    由于您已经在使用 Hibernate 和 Lucene,Hibernate Search 是一个很好的选择。

    Hibernate Search 主要提供的是一种机制,可以在数据更改时更新您的 Lucene 索引,并能够最大限度地利用您对 Hibernate 的了解,从而简化针对 Lucene 索引的搜索。

    您将能够指定要为每个实体中的哪些特定字段编制索引,以及根据需要添加多种类型的索引(例如,词干和全文)。您还可以设法为关联图建立索引,这样您就可以通过 Search/Lucene 进行相当复杂的查询。

    我发现最好依靠 Hibernate Search 来进行文本繁重的搜索,但恢复到普通的旧 Hibernate 来进行更传统的搜索并为复杂的对象图添加水合物以显示结果。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        我过去曾使用 Lucene 来索引数据库表。该解决方案效果很好,但请记住您需要维护索引。要么在每次持久化对象时更新索引,要么有一个守护进程索引器将数据库表转储到 Lucene 索引中。

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

        【讨论】:

        • 谢谢。我们已经使用 lucene 进行文档索引,所以我认为最好坚持使用同一个库。Lucene 怎么可能,例如,我想索引对象的一些关系?我是否必须索引整个表,或者我可以从主表及其某些关系中执行我需要的特定列?
        • 我这样做的方式是使用 SELECT 查询和 JOINS 来创建我的数据的“平面”结构,以便我可以在它们上运行索引器。这是一种方法。您还可以使用存储过程将数据扁平化为用于索引目的的特殊表
        【解决方案5】:

        一年前我会推荐 Compass。它擅长它的工作,并且在技术上仍然可以在我开发和维护的应用程序中愉快地运行。

        但是,Compass 没有更多的开发,而是转而使用 ElasticSearch。从该项目的网站上,我无法完全确定它是否已经为大时代做好了准备,甚至还真的活着。

        所以我改用 Hibernate Search,感觉不太好,但迁移仍处于初始阶段,所以我将保留一段时间的判断。

        【讨论】:

          【解决方案6】:

          所有项目都基于 Lucene。如果你想实现一个非常高级的功能,我建议你直接使用 Lucene。如果没有,您可以使用Solr,这是一个基于 lucene 的强大 API,可以帮助您从 DB 中进行索引和搜索。

          【讨论】:

          • 我认为我不需要太高级的功能,但想避免使用我们目前不使用的新库。我不确定我是否理解您为什么推荐 Solr - 它无论如何都是基于 lucene 构建的?你能再澄清一点吗?谢谢你!!!
          • 我给你一个例子:你必须对网络服务器进行 http 调用。在 java 中有套接字库可以帮助你做到这一点,但有更好的:apache commons http client。这正是实现该协议的内置库所带来的。 Solr 具有用于管理索引的内置 API、简单的全文搜索和简单的数据库集成以及设计为运行 servlet 容器的相同功能。
          猜你喜欢
          • 2011-07-24
          • 1970-01-01
          • 2012-12-27
          • 1970-01-01
          • 1970-01-01
          • 2014-07-08
          • 1970-01-01
          • 2010-09-17
          相关资源
          最近更新 更多