关于elasticsearch-rails/erasticsearch-persistence

这是Speeee冒险日历的第八天。

elasticsearch

三个月前,我被分配到一个我完全没有接触过的Elasticsearch项目上,里面充满了让我摸不着头脑的事情。我觉得网上关于elasticsearch-persistence的日语资料似乎很少,所以我希望能简单总结一下它。

我正在使用的环境

Elasticsearch(1.7.2)
Elasticsearch持久化(0.1.8)
Rails(4.2.3)
Ruby(2.2.3)

为什么选择使用持续性?

如果在应用程序中,想要将elasticsearch的搜索功能应用于存在数据库表的模型(继承了ActiveRecord的模型),可以通过使用Elasticsearch::Model来为该模型添加elasticsearch的功能。
然而,在我参与的这个项目中,我希望对不存在数据库表的模型(不继承ActiveRecord的模型)使用elasticsearch进行搜索,因此我决定使用persistence。

Elasticsearch::Persistence的两种实现方法

坚持有两种类型:Repository类型和Active Record类型。

代码库类型

在这种情况下,存储库负责对elasticsearch进行搜索、引用、保存和删除等操作,并且可以通过将值填充到save方法的存储库参数中来保存模型。这似乎是提供了存储库模式的功能。

活跃记录类型

这个是为了让使用者能够像使用ActiveRecord模型一样,直接利用Elasticsearch进行搜索等操作的工具。
这次我们选择了这个工具。
原因只是因为可以像平时使用rails一样方便。

模型(Model)与仓库(Repository)之间的关系。

即使使用ActiveRecord类型进行实现,内部实际上仍使用了Repository,并且其使用被隐藏起来。例如,假设存在包含了Elasticsearch::Persistence::Model的Hoge模型。

Hoge.gateway

在这里存储了Elasticsearch::Persistence::Repository。

如何使用Elasticsearch::Persistence::Model。

include Elasticsearch::Persistence::Model

这样写在Elasticsearch::Persistence::Model中就可以了。Elasticsearch::Persistence::Model本身已经包含了virtus和ActiveModel,只需引入它,就可以轻松地创建基本模型。

class Hoge
  include Elasticsearch::Persistence::Model

  attribute :fuga,  Integer
  validates :fuga,  presence: true
end

如果用.save来保存,它会为你保存,如果用.search(#{query})来搜索,它会帮你搜索并返回搜索结果。
返回的搜索结果是Elasticsearch::Persistence::Repository::Response::Results,但是可以使用each等方法来展开,直接对调用的模型进行操作。
由于是直接调用的模型,所以注意在只在父类中include,而在其子类中进行搜索时,结果将存储在父类中,需要注意一些细节。
另外,如果使用aggregation,情况就不一样了,需要直接提取值并将其存储在模型中进行操作。

在中文中,对索引和文档的指定方法可以这样描述:

index_name 'hoge'
document_type 'fuga'

如果写了就可以OK。
如果不写的话,会根据类名自动推断并创建。

module Elasticsearch
  class Hoge
    include Elasticsearch::Persistence::Model

    index_name 'hoge'        # add
    document_type 'fuga'     # add

    attribute :fuga,  Integer
    validates :fuga,  presence: true
  end
end

强制更新索引

如果在像RSPEC等用于实际使用Elasticsearch的测试中,希望在将数据放入Elasticsearch后立即进行反映,

{Elasticsearch::Model}.__elasticsearch__.create_index!
{Elasticsearch::Model}.__elasticsearch__.flush_index!

写作如下,但在持久性的情况下:

{Elasticsearch::Persistence::Model}.gateway.create_index!
{Elasticsearch::Persistence::Model}.gateway.flush_index!

这意味着,在持久化的情况下,gateway是与__elasticsearch__相对应的。因此,如果你使用Elasticsearch::Model的文章,将其中的__elasticsearch__替换为gateway通常能够解决许多问题。

根据不同的环境修改主机。

非常普通

Elasticsearch::Persistence.client = Elasticsearch::Client.new(host: ENV['ELASTICSEARCH_HOST'], logs: Rails.env.development?, trace: Rails.env.development?)

这篇文章主要参考了Elasticsearch::Model的内容。
参考资料:使用RSpec编写Elasticsearch测试。

最后

我总结了使用`persistence`相比`Elasticsearch::Model`在基本功能上的区别。当时我对于使用`persistence`感到很困惑,因为我对此一无所知,并且有很多怀疑之处。虽然当时找到使用`persistence`的文章很少,让我感到困惑,但现在回顾起来,只要抓住要点,参考使用`Elasticsearch::Model`的文章就可以了。

bannerAds