Solr vs Hibernate Search - 选择何时以及何时选择?

时间:2011-05-20 07:32:56

标签: hibernate solr hibernate-search

我们正在构建电子商务应用程序。我们正在使用JAVA堆栈与Hibernate和Spring Framework。与所有电子商务应用程序一样,我们需要在我们的网站中构建搜索功能。

因此,我们遇到了Hibernate SearchApache Solr。有人可以列出它们的优点和缺点,以便我们可以为企业搜索选择理想的解决方案吗?

6 个答案:

答案 0 :(得分: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 Server中的客户详细信息。

@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 :(得分:15)

除了已经说过的内容,在群集环境中:

<强>休眠搜索:

缺点:

  • 需要主/从组合并不总是可行的,特别是当您的构建/部署过程无法区分节点时(所有节点的战争相同)。
  • 索引与运行Hibernate的应用程序驻留在同一服务器/进程中,因此每个应用程序节点都有一个索引。这有时候有点矫枉过正。
  • 除非负载均衡器使用会话粘性,否则不是实时搜索。

优点:

  • 零到小配置。只需将jar放入类路径中即可。
  • Hibernate与Lucene之间的桥梁非常直截了当。只是注释实体和voilá!

<强>的Solr / SolrCloud:

  • 它与自己的应用程序分离。
  • 不是实时搜索,就像hibernate-search。
  • 需要重新启动才能更改架构。
  • SolrCloud并不是最容易配置的框架。
  • 没有直接的Hibernate桥。你必须编写自己的Hibernate监听器代码并将它们绑定到post- [insert | delete | update]事件(或找到一个开源的)

<强> ElasticSearch

  • 服务器独立于应用程序,就像solr。
  • 到目前为止,最容易在群集/云中进行配置。
  • 实时
  • 也没有直接的Hibernate桥。 (GitHub上的es-hibernate-connector)

我个人在云端运行时更喜欢ElasticSearch。

答案 2 :(得分:7)

Apache Solr主要用于全文搜索:如果要在大量文档中查找单词(例如单数和复数),其中每个文档的大小从一个段落到几个页面。如果你不使用它来进行文本搜索,那么Solr可能不会比常规数据库更好,但只能用于int和varchar搜索。

此链接可能对您有用:

http://engineering.twitter.com/2011/04/twitter-search-is-now-3x-faster_1656.html

答案 3 :(得分:5)

还有另一种方法是将它们放在一起并将它们的优点结合在一起 看看:Combining the power of Hibernate Search and Solr
我一起使用它们并且工作正常 Hibernate搜索为我提供了所有实体注释和&amp;分析和更改事务边界中的集合,而Solr为我提供了具有1:m方面,集群等强大功能的最佳搜索引擎......

答案 4 :(得分:1)

听起来像需要阅读其中每一个的利弊。有大量文档可供使用。

如果您想要我的意见,我会说使用Hibernate的Hibernate搜索是有意义的。当hibernate执行数据库操作时以及仅在提交数据库事务时,才会更新搜索索引。

答案 5 :(得分:1)

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

Solr是一个建立在Lucene之上的框架(两个项目都应该在某一天合并,但这还有很长的路要走)。 Solr和Lucene之间的差异在another SO post中解释。