Solr和Hibernate Search - 选择哪个以及何时选择?

28
我们正在构建一款电子商务应用程序。我们使用的是带有Hibernate和Spring Framework的JAVA堆栈。与所有电子商务应用程序一样,我们需要在自己的应用程序中构建搜索功能。
因此,我们发现了Hibernate SearchApache Solr。有人能列出它们各自的优缺点,以便我们可以选择最理想的企业搜索解决方案吗?

1
这不是一个答案,而是一个建议:您可能还想考虑ElasticSearch,它与Solr非常相似,并且可以处理扩展。http://www.elasticsearch.org/。http://engineering.socialcast.com/2011/05/realtime-search-solr-vs-elasticsearch/ - mistagrooves
每个架构师/开发人员都会回答...这取决于很多问题。你的电子商务应用有多大?例如用户数量?主要是读取还是写入?搜索功能有多广泛? - Steve Casey
@Steve 这是一个更多读取的应用程序。我认为任何电子商务应用程序都比写入更多阅读。无论如何,我想要一个通用的,这样将有助于未来的寻求者 :) - Lucky Murari
@mistagrooves 看起来不错,我会去看一下 :) - Lucky Murari
6个回答

17

假设您正在使用基于注释的配置的Hibernate作为Web应用程序的持久化层。那么,您可以使用与注释一样的模型类(如下所示)来使用Solr服务器特定的注释来设置它们在Solr服务器中的索引。

我将给出一个实现此操作的示例。

以下类是一个没有Solr注释的客户端模型类。

@Entity
@Table(name="Customer")
public class Customer {

    private int customerId;
    private String customerName;
    private String customerAddress;


    @Id     
    public int getCustomerId() {
        return customerId;
    }
    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerAddress() {
        return customerAddress;
    }
    public void setCustomerAddress(String customerAddress) {
        this.customerAddress = customerAddress;
    }



}

现在,让我们使用Solr注释来索引客户在Solr服务器中的详细信息。

@Entity
@Table(name="Customer")
public class Customer {
    @Field
    private int customerId;
    @Field
    private String customerName;
    @Field
    private String customerAddress;


    @Id     
    public int getCustomerId() {
        return customerId;
    }
    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerAddress() {
        return customerAddress;
    }
    public void setCustomerAddress(String customerAddress) {
        this.customerAddress = customerAddress;
    }



}

只需在要索引到Solr服务器的字段上添加@Field属性。

然后问题是如何告诉Solr对该模型进行索引。可以按以下方式完成。

假设您要将名为Alex的客户持久化到数据库中,则将数据添加到Alex中,如下所示:

Customer alex = new Customer();
alex.setCustomerName("Alex Rod");
alex.setCustomerAddress("101 washington st, DC");

在将这个alex对象保存到数据库后,你需要告诉Solr对这个数据对象进行索引。 操作如下。

session.save(alex);

        session.getTransaction().commit();


        String url = "http://localhost:8983/solr";
        SolrServer server = null;
        try {
            server = new CommonsHttpSolrServer(url);
            server.addBean(alex);
            server.commit();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

本文介绍了使用Hibernate技术进行Solr索引的相关内容,非常简单明了。我已经向您解释了如何使用它的基本思想。我们从一个商业应用程序中获得了这个例子,其中我们使用了以上方法来实现搜索功能。


1
感谢您的出色实现。但我的主要问题是关于利弊分析,因此希望得到答案。 - Lucky Murari

15

除了之前提到的内容外,在群集环境下:

Hibernate-search:

缺点:

  • 需要主/从组合,这并非总是可行的,特别是当您的构建/部署过程没有区分节点时(所有节点使用相同的war文件)。
  • 索引托管在与运行Hibernate应用程序的服务器/进程中,因此每个应用程序节点有一个索引。有时这有点过度。
  • 除非负载均衡器使用会话黏性,否则它不是实时搜索。

优点:

  • 零至少配置。只需将jar文件放入类路径即可。
  • Hibernate和Lucene之间的桥梁非常直接。只需对实体进行注释即可!

Solr/SolrCloud:

  • 它与应用程序本身解耦。
  • 与hibernate-search一样,没有实时搜索。
  • 更改模式需要重新启动。
  • SolrCloud不是最容易配置的框架。
  • 没有直接的Hibernate桥梁。您必须编写自己的Hibernate监听器并将它们绑定到post-[insert|delete|update]事件上(或找到一个开源的)

ElasticSearch

  • 服务器独立于应用程序,就像solr一样。
  • 它是迄今为止在群集/云中最容易配置的。
  • 它是实时的。
  • 同样没有直接的Hibernate桥梁。(es-hibernate-connector在GitHub上)

个人而言,在云中运行时我更喜欢ElasticSearch。


7

它对我的研究很有帮助 :)但我仍然会等待更完整的答案才接受它。 - Lucky Murari
5
我完全不同意这个观点。在Solr中,您可以索引任何想要的内容,并根据应用程序需要进行配置。它只是Lucene的一个封装接口,因此具有Lucene的所有功能。Solr默认情况下非常可配置、强大和快速,但如果需要更多功能,则编写插件来执行自定义操作并不困难。而且现在,有了SolrCloud,它比普通数据库快几倍,还带有基于Web的查询语言、过滤器、缓存等功能。 - laloumen
我并不是说Solr不能完成这个任务,而是如果情景是标准的关系型数据库情景,那么使用标准的SQL数据库可能更加合适(例如join等操作)。 - Bob Yoplait
@2014 这还有用吗? - Vish

6
另一种选择是将它们结合起来,充分发挥它们的优点。
请查看:Hibernate Search和Solr的结合
我正在使用它们并且效果不错。
Hibernate Search为我提供了所有实体注释和分析,并在事务边界内更改集合,而Solr则为我提供了最好的搜索引擎,具有出色的功能,如1:m外观、聚类等。

你有这个的实现示例吗?链接提供的不足以让我朝着正确的方向前进。 - schmimd04
我可以尝试构建一些示例。但是你仍然需要使用solrj客户端进行查询。这对你有帮助吗? - Avner Levy
是的。我大部分的搜索都将通过Solr HTTP接口直接完成。我希望使用Hibernate Search轻松获取索引中的文档,并利用实体注释和FieldBridges。 - schmimd04
4
请查看https://github.com/avner-levy/hibernate_search_solr_integration。这只是一个非常基本的示例,但应该可以帮助您理解。我会在接下来的几天内进行改进。 - Avner Levy
非常感谢!BackendQueueProcessor的实现正是我需要看到的! - schmimd04

1

听起来你需要阅读一下关于它们各自的优缺点的相关资料。有大量的文档可供参考。

如果你想要我的意见,我会建议你在使用 Hibernate 时使用 Hibernate Search。当 Hibernate 执行数据库操作并且仅在提交数据库事务时才会更新搜索索引。


不要单独列出优点和缺点。我想要将它们进行比较。 - Lucky Murari

1

Hibernate搜索是Hibernate和Lucene之间的"桥梁"。换句话说,它使得持久化的Hibernate实体在Lucene索引中自动可搜索。

Solr是建立在Lucene之上的一个框架(这两个项目有一天会合并,但还有很长的路要走)。Solr和Lucene之间的区别在另一篇SO文章中进行了解释。


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