是否可以在已加载的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加载记录中?
答案 0 :(得分:1)
据我所知,不可能获得将文档字段合并到加载的记录中的响应。
通常,我宁愿尽可能地完全依赖索引文档中的数据(使用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索引中的特定记录的文档可能会有所帮助,通常我可以通过在Product类中定义以下方法来做到这一点:
def es_document
return nil unless doc = Product.search_index.retrieve(self).presence
Hashie::Mash.new doc
end
答案 1 :(得分:1)
您可以使用select: true
和with_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