索引ElasticSearch中的方法结果(Tire + ActiveRecord)

时间:2012-11-28 07:37:40

标签: ruby-on-rails elasticsearch tire

我正在使用Tire和ActiveRecord为elasticsearch索引数据集。我有一个Artist模型,has_many: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

这只是忽略了索引方法。根据{{​​3}}等其他答案,我尝试了这个:

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文档,并没有找到这个模式的工作示例。谢谢你的想法!

1 个答案:

答案 0 :(得分:6)

所以,在这里将解决方案包括在索引问题中。

索引关联

索引方法的一种方法是将其包含在to_json调用中:

def to_indexed_json
  to_json( 
    :only   => [ :id, :name, :normalized_name, :url ],
    :methods   => [ :primary_image_original, :primary_image_thumbnail, :account_balance ]
  )
end

另一个,更优选的是,在映射块中使用: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 查询:对于您索引的每个艺术家,您都会发出图像查询(原始和缩略图)。一种更高效的方法是在一个查询中加入相关记录;请参阅Rails指南中的Eager Loading Associations

轮胎Index#import方法, 以及导入Rake任务,允许您传递参数,然后将这些参数发送到网上的分页方法。

让我们比较天真的方法:

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.importArticle.import(include: ['comments'])。作为旁注,这个确切的问题是在 Tire 中的整个导入工具链中支持params哈希的原因。