正在searchkick中加载的记录中获取ElasticSearch文档字段



是否可以在加载的AR记录中获取ElasticSearch文档字段?

这里有一个要点来说明我的意思:https://gist.github.com/allomov/39c30905e94c646fb11637b45f43445d

在这种情况下,我希望在从ES获得响应后避免total_price的额外计算。我目前看到的解决方案是包括关系并为每个记录运行total_price计算,在我看来,这不是执行此操作的最佳方式。

result = Product.search("test", includes: :product_components).response
products_with_total_prices = result.map do |product|
{
product: product
total_price: product.product_components.map(&:price).compact.sum
}
end

你能告诉我是否可以将ES文档字段混合到AR加载的记录中吗?

据我所知,不可能得到将文档字段合并到加载记录中的响应。

通常,我更喜欢在可能的情况下完全依赖索引文档中的数据(使用load: false作为搜索选项(,并且在必要时只加载AR记录作为第二步。例如:

result = Product.search("test", load: false).response
# If you also need AR records, could do something like:
product_ids    = result.map(&:id)
products_by_id = {}
Product.where(id: product_ids).find_each do |ar_product|
products_by_id[ar_product.id] = ar_product
end
merged_result = result.map do |es_product|
es_product[:ar_product] = products_by_id[es_product.id]}
end

此外,检索存储在ES索引中的特定记录的文档可能会有所帮助,我通常会通过在您的产品类中定义以下方法来做到这一点:

def es_document
return nil unless doc = Product.search_index.retrieve(self).presence
Hashie::Mash.new doc
end

您可以使用select: truewith_hit方法将记录和搜索文档放在一起。例如:

result = Product.search("test", select: true)
products_with_total_prices =
result.with_hit.map do |product, hit|
{
product: product,
total_price: hit["_source"]["total_price"]
}
end

最新更新