“elasticsearch-model的import方法中的transform参数非常有用。”
我在工作中改进搜索功能时的备忘录,想公开一些不包含机密信息的部分。
Hoge.__elasticsearch__.import的定义
总的来说
__find_in_batches(options) do |batch|
response = client.bulk \
index: target_index,
type: target_type,
body: __batch_to_bulk(batch, transform)
yield response if block_given?
errors += response['items'].select { |k, v| k.values.first['error'] }
end
在内部,使用find_in_batch每次1000个,以bulk API将数据一次性批量插入到Elasticsearch中是一个很棒的功能。 (长话短说,find_in_batches默认是1000是由ActiveRecord定义,而不是Elasticsearch-model。 https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/relation/batches.rb#L126 )
不仅可以使用批量插入,还可以进行更新和删除。
Elasticsearch的批量API是一个示例,可以
[
{ delete: { id: 123} },
{ index: { id: 124, data: { title: elasticsearch-modelが便利, ......... } } },
{ delete: { id: 125 } }
]
当指定像这样的有效负载时,
-
- 123, 125はインデックスされていたら削除する(delete if exists)
- 124は、まだインデックスされていなかったらインデックスする(insert or update)
也可以做一些复杂的事情。
在先前提到的import方法中,传递给bulk API的payload是通过body: __batch_to_bulk(batch, transform)实现的,在进一步查看其定义时。
def __batch_to_bulk(batch, transform)
batch.map { |model| transform.call(model) }
end
看起来是将transform应用于一个名为model的列表。
这个transform,默认情况下在https://github.com/elastic/elasticsearch-rails/blob/v6.0.0/elasticsearch-model/lib/elasticsearch/model/adapters/active_record.rb#L114中定义。
def __transform
lambda { |model| { index: { _id: model.id, data: model.__elasticsearch__.as_indexed_json } } }
end
这是一种将模型直接插入或更新的转换方式。
如果存在一种类似于下書き與公開後不分开模型的文章模型,則這種轉換非常實用。
# 公開済みの記事はインデックスする
Article.__elasticsearch__.import(scope: :published)
# 下書き状態のもの、公開後に下書きに戻されたものは、インデックスがある場合には削除する
Article.__elasticsearch__.import(
scope: :draft,
transform: ->(model) {
{ delete: { _id: model.id } }
}
)
通过使用 transform 参数,可以选择性地将已发布的内容同步到 Elasticsearch 中。
或者,取决于可读性的权衡。
Article.__elasticsearch__.import(
transform: lambda do |article|
if article.published?
{ index: { _id: article.id, data: article.__elasticsearch__.as_indexed_json } }
else
{ delete: { _id: article.id } }
end
end
)
如果这样做,似乎可以减少调用bulk API的次数自体。
请将以下内容用中文进行同义转述,只需给出一种选项:
Michelle is excited to visit her grandparents in China during summer vacation.
首先,在2018年版的「Web服务(Rails)+手机应用程序的制作时不应该做的事情」中,我提到了模型分离的重要性。不过,当存在历史经验等各种原因无法实现模型分离时,我认为transform参数是非常有用的解决方案。