将Elasticsearch集成到Rails应用程序中

Elasticsearch是什么?

Elasticsearch是由Elastic公司开发的开源全文搜索引擎,可快速从大量文档中提取包含目标词汇的文档。

在Rails应用中处理Elasticsearch的概念

1. 所有搜索数据都存储在全文搜索引擎中。
2. 当应用程序进行搜索时,会向搜索引擎发出查询,并返回结果。
3. 当应用程序中的搜索数据更新时,会与搜索引擎进行同步,更新搜索引擎中的数据。

用Rails应用程序处理Elasticsearch

创建索引

在 Elasticsearch 中,会创建索引作为数据的存储位置。
类似于关系型数据库中的表。

首先,为了在Elasticsearch中处理Rails模型,需要安装一个专用的gem。在Gemfile中写下以下内容,然后运行bundle install命令。

gem 'elasticsearch-model', github: 'elastic/elasticsearch-rails'
gem 'elasticsearch-rails', github: 'elastic/elasticsearch-rails'

当bundle install完成后,将在Elasticsearch中创建索引。
在想要作为搜索目标的模型中,要包含Elasticsearch::Model。

class Article < ActiveRecord::Base
  include Elasticsearch::Model
end

现在可以使用这个模型准备好操作Elasticsearch了。
可以使用以下代码创建索引。

Article.__elasticsearch__.create_index! force:true

将文档放入索引中

在Elasticsearch中,将存储在索引中的数据称为文档。
索引中存放着想要搜索的数据。

使用以下的代码将文档导入到Elasticsearch中。


Article.import

使用此方法将文档注册到Elasticsearch的索引中。

搜索文件

可以通过向Elasticsearch发送查询来搜索文档。
您可以通过以下方式从Rails向Elasticsearch发送查询。

response = Article.search 'hoge'

您可以通过在参数中指定搜索字符串来搜索文档。

从前台接收参数并进行搜索的代码可以写成以下方式。

def index
  @articles = Article.search(params)
end

当Rails侧的搜索对象记录被更新时,相应地,Elasticsearch的文档也会被更新。

当实际运营服务时,如果Rails的记录被更新,则需要更新Elasticsearch的文档。

想要简单地更新Elasticsearch文档,可以按照以下方式进行实现。

Article.first.__elasticsearch__.update_document

除此之外,还有一个名为delete_document的方法,使用它可以删除文档。

即使不明确地写出来,您也可以自动更新文档,只需更新记录。
使用gem elasticsearch-model,如果在Model中包含Elasticsearch::Model::Callbacks,那么在更新记录时会自动发送查询以更新Elasticsearch文档。

class Article
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks
end

将Elasticsearch集成到Rails应用中。

我来制作Article模型搜索相关的处理。

require 'active_support/concern'
module Article::Searchable
  extend ActiveSupport::Concern

  included do
    include Elasticsearch::Model

    index_name "article"

    settings index: {
      number_of_shards: 1,
      number_of_replicas: 0
    } do
      mapping _source: { enabled: true } do
        indexes :id, type: 'integer', index: 'not_analyzed'
        indexes :title, type: 'string'
        indexes :content, type: 'text'
      end
    end
  end

  module ClassMethods
    def create_index!(options={})
      client = __elasticsearch__.client
      client.indices.delete index: "article" rescue nil if options[:force]
      client.indices.create index: "article",
      body: {
        settings: settings.to_hash,
        mappings: mappings.to_hash
      }
    end
  end
end

在模块中,包含 Elasticsearch::Model,以便使用一组便捷的方法。

index_name是索引名称,settings中写入索引的配置。
number_of_shards和number_of_replicas是关于分片和副本的设置,与容错性和性能相关。

映射(mapping)确定了索引的定义方式。它类似于关系型数据库(RDB)中的表模式。

create_index!是一个实际创建索引的助手函数。
由于可以通过elasticsearch.client获取Elasticsearch客户端对象,
所以可以通过这个客户端进行各种操作。

将已创建的模块包括在模型中。

class Article < ActiveRecord::Base
  include Article::Searchable
  def self.search_message(keyword)
    if keyword.present?
      query = {
        "query": {
          "match": {
            "message": keyword
          }
        }
      }
      Article.__elasticsearch__.search(query)
    else
      Article.none
    end
  end
end

根据收到的关键字构建搜索查询,并将其传递给Article.elasticsearch.search。
通过调用elasticsearch.search来对Article模型进行查询,elasticsearch-rails和elasticsearch-model将会帮助我们发送查询请求。

控制器的内容如下。

class ArticlesController < ApplicationController
  def search
    @keyword = params[:keyword]
    @articles = Article.search_message(@keyword).paginate(page: params[:page])
  end

以下是在Rails应用程序中集成Elasticsearch的一个示例。

请参考

使用elasticsearch-rails在Rails中运行Elasticsearch【适合初学者】,总结了将Elasticsearch集成到Rails应用程序的搜索处理所做的事情。

广告
将在 10 秒后关闭
bannerAds