我正在使用 Tire 和 ActiveRecord 为 elasticsearch 的数据集编制索引。我有一个 Artist 模型,它有很多 :images。如何索引返回特定图像的 Artist 模型的方法?还是引用关联模型的方法?我想要的艺术家结果将包括与艺术家关联的主要图像的路径(原始图像和缩略图)。
我试过这个映射:
mapping do
indexes :id, :index => :not_analyzed
indexes :name
indexes :url
indexes :primary_image_original
indexes :primary_image_thumbnail
end
引用这些 Artist 方法:
def primary_image_original
return images.where(:priority => 'primary').first.original
end
def primary_image_thumbnail
return images.where(:priority => 'primary').first.thumbnail_150
end
这只是忽略了索引方法。基于其他答案,如 Elasticsearch, Tire, and Nested queries / associations with ActiveRecord ,我试过这个:
mapping do
indexes :id, :index => :not_analyzed
indexes :name
indexes :url
indexes :images do
indexes :original
indexes :thumbnail_150
indexes :priority
end
end
def to_indexed_json
to_json(include: { images: { only: [:original, :thumbnail_150, :priority] } } )
end
但这也不会返回我所追求的。我花了几个小时谷歌搜索和阅读 elasticsearch 和 Tire 文档,但没有找到可遵循的此模式的工作示例。感谢您的想法!
最佳答案
因此,请在此处包含您对索引问题的解决方案。
索引关联
索引方法的一种方法是将其包含在 to_json
调用中:
def to_indexed_json
to_json(
:only => [ :id, :name, :normalized_name, :url ],
:methods => [ :primary_image_original, :primary_image_thumbnail, :account_balance ]
)
end
另一种更可取的方法是在映射 block 中使用 :as
选项:
mapping do
indexes :id, :index => :not_analyzed
indexes :name
# ...
# Relationships
indexes :primary_image_original, :as => 'primary_image_original'
indexes :account_balance, :as => 'account_balance'
end
在导入时处理 n+1 个查询
索引速度慢的问题很可能是由于数据库中的 n+1 个查询造成的:对于您索引的每个艺术家,您都会发出图像查询(原始和缩略图)。一种更高效的方法是在一个查询中加入关联的记录;见Eager Loading Associations在 Rails 指南中。
轮胎 Index#import
方法,
和 import Rake 任务,允许您传递参数,然后将这些参数发送到 paginate 方法。
所以让我们比较一下朴素的方法:
bundle exec rake environment tire:import CLASS=Article FORCE=true
Article Load (7.6ms) SELECT "articles".* FROM "articles" LIMIT 1000 OFFSET 0
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE ("comments".article_id = 1)
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE ("comments".article_id = 2)
...
Comment Load (0.3ms) SELECT "comments".* FROM "comments" WHERE ("comments".article_id = 100)
当我们传递 include
片段时:
bundle exec rake environment tire:import PARAMS='{:include => ["comments"]}' CLASS=Article FORCE=true
Article Load (8.7ms) SELECT "articles".* FROM "articles" LIMIT 1000 OFFSET 0
Comment Load (31.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".article_id IN (1,2, ... ,100))
好多了 :) 请尝试一下,如果它能解决您的问题,请告诉我。
您也可以在 Rails 控制台中尝试:Article.import
与 Article.import(include: ['comments'])
。作为旁注,这个确切的问题是在 Tire 的整个导入工具链中支持 params
散列的原因。
关于ruby-on-rails - 索引 ElasticSearch 中某个方法的结果(Tire + ActiveRecord),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13600086/