【问题标题】:Index the results of a method in ElasticSearch (Tire + ActiveRecord)索引 ElasticSearch 中方法的结果(Tire + ActiveRecord)
【发布时间】:2012-11-16 00:14:06
【问题描述】:

我正在使用 Tire 和 ActiveRecord 为弹性搜索的数据集编制索引。我有一个 Artist 模型,它有_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

这只是忽略了索引方法。根据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 文档,但还没有找到可以遵循的这种模式的工作示例。感谢您的想法!

【问题讨论】:

  • 请注意,Artist 模型上的其他索引字段(名称和 url)已按预期使用上述映射进行索引和搜索。
  • 您能否尝试使用:as 选项 - 不幸的是,我目前没有时间深入研究。
  • 另外,您能否提供一个带有to_indexed_json输出链接的paste/hastebin/etc?
  • 感谢您的快速回复,@karmi! (感谢您提供的很棒的宝石!)我能够找出两种方法来索引 Artist 模型的方法。请在此处查看我的馅饼:pastie.org/5456743。但是,我现在看到的问题是这两种方法都将索引时间增加了至少 60 倍。如果没有这些方法,索引一批 1000 条记录只需不到一秒的时间。使用这些方法,索引一批 1000 条记录需要一分钟多的时间。在这种情况下如何加快索引速度?我有几百万条记录要索引。这里有更好的方法吗?再次感谢。
  • 用相关方法更新了馅饼:pastie.org/5456766

标签: ruby-on-rails elasticsearch tire


【解决方案1】:

所以,在这里包含您对索引问题的解决方案。

索引关联

索引方法的一种方法是将其包含在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 方法, 和 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 哈希的原因。

【讨论】:

  • +1 为答案。我有一个 CPU 密集型功能,我想通过 Elastic Search 对其进行索引。但是这个函数需要一些参数,我无法避免这些参数。我的问题是有什么方法可以索引带有参数的函数。非常感谢。
猜你喜欢
  • 2013-11-19
  • 2014-11-12
  • 1970-01-01
  • 2012-04-21
  • 2012-07-26
  • 2012-11-10
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
相关资源
最近更新 更多